Compare commits

...

3 Commits

Author SHA1 Message Date
TSRBerry
79a1314ee4 [Ryujinx.Cpu] Address dotnet-format issues (#5365)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0052 warnings

* Silence dotnet format IDE0059 warnings

* Address or silence dotnet format IDE1006 warnings

* Address dotnet format CA1816 warnings

* Address most dotnet format whitespace warnings

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Remove a few unused parameters

* Adjust namespaces

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Fix and silence a few dotnet-format warnings again

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Address review feedback

* Remove redundant unsafe modifiers

* Fix build issues

* Add GC.SuppressFinalize() call

* Add trailing commas and fix naming rule violations

* Remove unused members and assignments
2023-07-01 02:18:52 +00:00
TSRBerry
e9848339dd [Ryujinx.Tests] Address dotnet-format issues (#5389)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Fix new dotnet-format issues after rebase

* Address review comments

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* cpu tests: Disable CA2211 for CodeBaseAddress and DataBaseAddress

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* First dotnet format pass

* Fix naming rule violations

* Remove naming rule violation exceptions

* Fix comment style

* Use targeted new

* Remove redundant code

* Remove comment alignment

* Remove naming rule exceptions

* Add trailing commas

* Use nameof expression

* Reformat to add remaining trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-07-01 02:14:34 +00:00
TSRBerry
6e28a4dd13 [Ryujinx.Ui.Common] Address dotnet-format issues (#5392)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Silence dotnet format IDE0060 warnings

* Address dotnet format CA1401 warnings

* dotnet-format fixes after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Another rebase, another dotnet format run

* Run dotnet format style after rebase

* Add comments to disabled warnings

* Remove a few unused parameters

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Address IDE0251 warnings

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* Small optimizations

* Remove alignment

* Apply formatting

* Fix build issues

* Final pass for dotnet format

* Add trailing commas

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-06-29 02:39:22 +02:00
134 changed files with 3407 additions and 3019 deletions

View File

@@ -32,6 +32,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Input;
using Ryujinx.Input.HLE;
using Ryujinx.Ui.App.Common;
using Ryujinx.Ui.Common;
using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Helper;
@@ -692,7 +693,7 @@ namespace Ryujinx.Ava
DiscordIntegrationModule.SwitchToPlayingState(Device.Processes.ActiveApplication.ProgramIdText, Device.Processes.ActiveApplication.Name);
_viewModel.ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata =>
ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata =>
{
appMetadata.LastPlayed = DateTime.UtcNow;
});

View File

@@ -42,7 +42,7 @@ namespace Ryujinx.Ava.UI.Controls
{
viewModel.SelectedApplication.Favorite = !viewModel.SelectedApplication.Favorite;
viewModel.ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata =>
ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.TitleId, appMetadata =>
{
appMetadata.Favorite = viewModel.SelectedApplication.Favorite;
});

View File

@@ -3,6 +3,7 @@ using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.HLE.FileSystem;
using Ryujinx.Ui.App.Common;
using System;
using System.IO;
using System.Linq;
@@ -74,7 +75,7 @@ namespace Ryujinx.Ava.UI.Models
}
else
{
var appMetadata = MainWindow.MainWindowViewModel.ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
var appMetadata = ApplicationLibrary.LoadAndSaveMetaData(TitleIdString);
Title = appMetadata.Title ?? TitleIdString;
}

View File

@@ -239,28 +239,28 @@ namespace Ryujinx.Ava.UI.Renderer
IPlatformHandle CreateMacOS()
{
// Create a new CAMetalLayer.
IntPtr layerClass = ObjectiveC.objc_getClass("CAMetalLayer");
IntPtr metalLayer = ObjectiveC.IntPtr_objc_msgSend(layerClass, "alloc");
ObjectiveC.objc_msgSend(metalLayer, "init");
ObjectiveC.Object layerObject = new("CAMetalLayer");
ObjectiveC.Object metalLayer = layerObject.GetFromMessage("alloc");
metalLayer.SendMessage("init");
// Create a child NSView to render into.
IntPtr nsViewClass = ObjectiveC.objc_getClass("NSView");
IntPtr child = ObjectiveC.IntPtr_objc_msgSend(nsViewClass, "alloc");
ObjectiveC.objc_msgSend(child, "init", new ObjectiveC.NSRect(0, 0, 0, 0));
ObjectiveC.Object nsViewObject = new("NSView");
ObjectiveC.Object child = nsViewObject.GetFromMessage("alloc");
child.SendMessage("init", new ObjectiveC.NSRect(0, 0, 0, 0));
// Make its renderer our metal layer.
ObjectiveC.objc_msgSend(child, "setWantsLayer:", 1);
ObjectiveC.objc_msgSend(child, "setLayer:", metalLayer);
ObjectiveC.objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
child.SendMessage("setWantsLayer:", 1);
child.SendMessage("setLayer:", metalLayer);
metalLayer.SendMessage("setContentsScale:", Program.DesktopScaleFactor);
// Ensure the scale factor is up to date.
_updateBoundsCallback = rect =>
{
ObjectiveC.objc_msgSend(metalLayer, "setContentsScale:", Program.DesktopScaleFactor);
metalLayer.SendMessage("setContentsScale:", Program.DesktopScaleFactor);
};
IntPtr nsView = child;
MetalLayer = metalLayer;
IntPtr nsView = child.ObjPtr;
MetalLayer = metalLayer.ObjPtr;
NsView = nsView;
return new PlatformHandle(nsView, "NSView");

View File

@@ -7,15 +7,13 @@ namespace Ryujinx.Cpu
{
public class AddressSpace : IDisposable
{
private const ulong PageSize = 0x1000;
private const int DefaultBlockAlignment = 1 << 20;
private enum MappingType : byte
{
None,
Private,
Shared
Shared,
}
private class Mapping : IntrusiveRedBlackTreeNode<Mapping>, IComparable<Mapping>
@@ -37,7 +35,7 @@ namespace Ryujinx.Cpu
ulong leftSize = splitAddress - Address;
ulong rightSize = EndAddress - splitAddress;
Mapping left = new Mapping(Address, leftSize, Type);
Mapping left = new(Address, leftSize, Type);
Address = splitAddress;
Size = rightSize;
@@ -93,7 +91,7 @@ namespace Ryujinx.Cpu
(var leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize);
PrivateMapping left = new PrivateMapping(Address, leftSize, leftAllocation);
PrivateMapping left = new(Address, leftSize, leftAllocation);
Address = splitAddress;
Size = rightSize;
@@ -181,7 +179,7 @@ namespace Ryujinx.Cpu
{
addressSpace = null;
MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
const MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
@@ -391,8 +389,6 @@ namespace Ryujinx.Cpu
ulong vaAligned = BitUtils.AlignDown(va, alignment);
ulong endAddressAligned = BitUtils.AlignUp(endAddress, alignment);
ulong sizeAligned = endAddressAligned - vaAligned;
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
for (; map != null; map = map.Successor)
@@ -436,8 +432,6 @@ namespace Ryujinx.Cpu
return;
}
ulong alignedSize = endAddressAligned - vaAligned;
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
for (; map != null; map = map.Successor)
@@ -495,9 +489,11 @@ namespace Ryujinx.Cpu
public void Dispose()
{
GC.SuppressFinalize(this);
_privateMemoryAllocator?.Dispose();
Base.Dispose();
Mirror.Dispose();
}
}
}
}

View File

@@ -42,6 +42,6 @@ namespace Ryujinx.Cpu.AppleHv.Arm
WatchpointSameEl = 0b110101,
BkptAarch32 = 0b111000,
VectorCatchAarch32 = 0b111010,
BrkAarch64 = 0b111100
BrkAarch64 = 0b111100,
}
}
}

View File

@@ -4,7 +4,7 @@ namespace Ryujinx.Cpu.AppleHv
{
public class DummyDiskCacheLoadState : IDiskCacheLoadState
{
#pragma warning disable CS0067
#pragma warning disable CS0067 // The event is never used
/// <inheritdoc/>
public event Action<LoadState, int, int> StateChanged;
#pragma warning restore CS0067
@@ -14,4 +14,4 @@ namespace Ryujinx.Cpu.AppleHv
{
}
}
}
}

View File

@@ -18,18 +18,16 @@ namespace Ryujinx.Cpu.AppleHv
private const ulong AllocationGranule = 1UL << 14;
private readonly ulong _asBase;
private readonly ulong _asSize;
private readonly ulong _backingSize;
private readonly HvAddressSpaceRange _userRange;
private readonly HvAddressSpaceRange _kernelRange;
private MemoryBlock _kernelCodeBlock;
private readonly MemoryBlock _kernelCodeBlock;
public HvAddressSpace(MemoryBlock backingMemory, ulong asSize)
{
(_asBase, var ipaAllocator) = HvVm.CreateAddressSpace(backingMemory);
_asSize = asSize;
_backingSize = backingMemory.Size;
_userRange = new HvAddressSpaceRange(ipaAllocator);
@@ -58,20 +56,20 @@ namespace Ryujinx.Cpu.AppleHv
_kernelCodeBlock.Write(KernelRegionEretOffset, 0xD69F03E0u); // ERET
ulong kernelCodePa = ipaAllocator.Allocate(AllocationGranule);
HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_EXEC).ThrowOnError();
HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, HvMemoryFlags.Read | HvMemoryFlags.Exec).ThrowOnError();
_kernelRange.Map(KernelRegionCodeOffset, kernelCodePa, KernelRegionCodeSize, ApFlags.UserNoneKernelReadExecute);
}
public void InitializeMmu(ulong vcpu)
{
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset);
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR0_EL1, _userRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR1_EL1, _kernelRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_MAIR_EL1, 0xffUL);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TCR_EL1, 0x00000011B5193519UL);
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_SCTLR_EL1, 0x0000000034D5D925UL);
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR0_EL1, _userRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR1_EL1, _kernelRange.GetIpaBase());
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.MAIR_EL1, 0xffUL);
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TCR_EL1, 0x00000011B5193519UL);
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.SCTLR_EL1, 0x0000000034D5D925UL);
}
public bool GetAndClearUserTlbInvalidationPending()
@@ -115,7 +113,7 @@ namespace Ryujinx.Cpu.AppleHv
MemoryPermission.ReadAndWrite => ApFlags.UserReadWriteKernelReadWrite,
MemoryPermission.ReadAndExecute => ApFlags.UserReadExecuteKernelRead,
MemoryPermission.ReadWriteExecute => ApFlags.UserReadWriteExecuteKernelReadWrite,
_ => throw new ArgumentException($"Permission \"{permission}\" is invalid.")
_ => throw new ArgumentException($"Permission \"{permission}\" is invalid."),
};
}
@@ -126,4 +124,4 @@ namespace Ryujinx.Cpu.AppleHv
HvVm.DestroyAddressSpace(_asBase, _backingSize);
}
}
}
}

View File

@@ -34,7 +34,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong size = (ulong)count * sizeof(ulong);
Allocation = blockAllocator.Allocate(size, PageSize);
AsSpan().Fill(0UL);
AsSpan().Clear();
if (hasNext)
{
@@ -42,7 +42,7 @@ namespace Ryujinx.Cpu.AppleHv
}
}
public unsafe Span<ulong> AsSpan()
public Span<ulong> AsSpan()
{
return MemoryMarshal.Cast<byte, ulong>(Allocation.Memory.GetSpan(Allocation.Offset, (int)Allocation.Size));
}
@@ -52,12 +52,10 @@ namespace Ryujinx.Cpu.AppleHv
private int _tlbInvalidationPending;
private readonly HvIpaAllocator _ipaAllocator;
private readonly HvMemoryBlockAllocator _blockAllocator;
public HvAddressSpaceRange(HvIpaAllocator ipaAllocator)
{
_ipaAllocator = ipaAllocator;
_blockAllocator = new HvMemoryBlockAllocator(ipaAllocator, (int)AllocationGranule);
}
@@ -129,7 +127,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong endVa = (va + size + PageMask) & ~((ulong)PageMask);
va &= ~((ulong)PageMask);
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth);
(ulong blockSize, _) = GetBlockSizeAndShift(depth);
while (va < endVa)
{
@@ -138,7 +136,7 @@ namespace Ryujinx.Cpu.AppleHv
int l = (int)(va >> (PageBits + (2 - depth) * LevelBits)) & LevelMask;
PtLevel nextTable = level.Next != null ? level.Next[l] : null;
PtLevel nextTable = level.Next?[l];
if (nextTable != null)
{
@@ -190,7 +188,7 @@ namespace Ryujinx.Cpu.AppleHv
ulong endVa = (va + size + PageSize - 1) & ~((ulong)PageSize - 1);
va &= ~((ulong)PageSize - 1);
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth);
(ulong blockSize, _) = GetBlockSizeAndShift(depth);
while (va < endVa)
{
@@ -204,7 +202,7 @@ namespace Ryujinx.Cpu.AppleHv
// First check if the region is mapped.
if ((pte & 3) != 0)
{
PtLevel nextTable = level.Next != null ? level.Next[l] : null;
PtLevel nextTable = level.Next?[l];
if (nextTable != null)
{
@@ -240,10 +238,10 @@ namespace Ryujinx.Cpu.AppleHv
pte &= ~3UL;
pte |= (depth == 2 ? 3UL : 1UL);
PtLevel level = new PtLevel(_blockAllocator, LevelCount, depth < 2);
PtLevel level = new(_blockAllocator, LevelCount, depth < 2);
Span<ulong> currentLevel = level.AsSpan();
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth);
(_, int blockShift) = GetBlockSizeAndShift(depth);
// Fill in the blocks.
for (int i = 0; i < LevelCount; i++)
@@ -334,7 +332,7 @@ namespace Ryujinx.Cpu.AppleHv
if ((currentTable[index] & 1) == 0)
{
PtLevel nextLevel = new PtLevel(_blockAllocator, LevelCount, hasNext);
PtLevel nextLevel = new(_blockAllocator, LevelCount, hasNext);
currentTable[index] = (nextLevel.Address & ~(ulong)PageMask) | 3UL;
level.Next[index] = nextLevel;
@@ -347,7 +345,7 @@ namespace Ryujinx.Cpu.AppleHv
}
}
private void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr)
private static void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr)
{
Span<ulong> currentTable = level.AsSpan();
@@ -367,4 +365,4 @@ namespace Ryujinx.Cpu.AppleHv
_blockAllocator.Dispose();
}
}
}
}

View File

@@ -1,245 +1,244 @@
using ARMeilleure.State;
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.Cpu.AppleHv
{
struct hv_vcpu_exit_exception_t
struct HvVcpuExitException
{
#pragma warning disable CS0649
public ulong syndrome;
public ulong virtual_address;
public ulong physical_address;
#pragma warning disable CS0649 // Field is never assigned to
public ulong Syndrome;
public ulong VirtualAddress;
public ulong PhysicalAddress;
#pragma warning restore CS0649
}
struct hv_vcpu_exit_t
struct HvVcpuExit
{
#pragma warning disable CS0649
public uint reason;
public hv_vcpu_exit_exception_t exception;
#pragma warning disable CS0649 // Field is never assigned to
public uint Reason;
public HvVcpuExitException Exception;
#pragma warning restore CS0649
}
enum hv_reg_t : uint
enum HvReg : uint
{
HV_REG_X0,
HV_REG_X1,
HV_REG_X2,
HV_REG_X3,
HV_REG_X4,
HV_REG_X5,
HV_REG_X6,
HV_REG_X7,
HV_REG_X8,
HV_REG_X9,
HV_REG_X10,
HV_REG_X11,
HV_REG_X12,
HV_REG_X13,
HV_REG_X14,
HV_REG_X15,
HV_REG_X16,
HV_REG_X17,
HV_REG_X18,
HV_REG_X19,
HV_REG_X20,
HV_REG_X21,
HV_REG_X22,
HV_REG_X23,
HV_REG_X24,
HV_REG_X25,
HV_REG_X26,
HV_REG_X27,
HV_REG_X28,
HV_REG_X29,
HV_REG_FP = HV_REG_X29,
HV_REG_X30,
HV_REG_LR = HV_REG_X30,
HV_REG_PC,
HV_REG_FPCR,
HV_REG_FPSR,
HV_REG_CPSR,
X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
FP = X29,
X30,
LR = X30,
PC,
FPCR,
FPSR,
CPSR,
}
enum hv_simd_fp_reg_t : uint
enum HvSimdFPReg : uint
{
HV_SIMD_FP_REG_Q0,
HV_SIMD_FP_REG_Q1,
HV_SIMD_FP_REG_Q2,
HV_SIMD_FP_REG_Q3,
HV_SIMD_FP_REG_Q4,
HV_SIMD_FP_REG_Q5,
HV_SIMD_FP_REG_Q6,
HV_SIMD_FP_REG_Q7,
HV_SIMD_FP_REG_Q8,
HV_SIMD_FP_REG_Q9,
HV_SIMD_FP_REG_Q10,
HV_SIMD_FP_REG_Q11,
HV_SIMD_FP_REG_Q12,
HV_SIMD_FP_REG_Q13,
HV_SIMD_FP_REG_Q14,
HV_SIMD_FP_REG_Q15,
HV_SIMD_FP_REG_Q16,
HV_SIMD_FP_REG_Q17,
HV_SIMD_FP_REG_Q18,
HV_SIMD_FP_REG_Q19,
HV_SIMD_FP_REG_Q20,
HV_SIMD_FP_REG_Q21,
HV_SIMD_FP_REG_Q22,
HV_SIMD_FP_REG_Q23,
HV_SIMD_FP_REG_Q24,
HV_SIMD_FP_REG_Q25,
HV_SIMD_FP_REG_Q26,
HV_SIMD_FP_REG_Q27,
HV_SIMD_FP_REG_Q28,
HV_SIMD_FP_REG_Q29,
HV_SIMD_FP_REG_Q30,
HV_SIMD_FP_REG_Q31,
Q0,
Q1,
Q2,
Q3,
Q4,
Q5,
Q6,
Q7,
Q8,
Q9,
Q10,
Q11,
Q12,
Q13,
Q14,
Q15,
Q16,
Q17,
Q18,
Q19,
Q20,
Q21,
Q22,
Q23,
Q24,
Q25,
Q26,
Q27,
Q28,
Q29,
Q30,
Q31,
}
enum hv_sys_reg_t : ushort
enum HvSysReg : ushort
{
HV_SYS_REG_DBGBVR0_EL1 = 0x8004,
HV_SYS_REG_DBGBCR0_EL1 = 0x8005,
HV_SYS_REG_DBGWVR0_EL1 = 0x8006,
HV_SYS_REG_DBGWCR0_EL1 = 0x8007,
HV_SYS_REG_DBGBVR1_EL1 = 0x800c,
HV_SYS_REG_DBGBCR1_EL1 = 0x800d,
HV_SYS_REG_DBGWVR1_EL1 = 0x800e,
HV_SYS_REG_DBGWCR1_EL1 = 0x800f,
HV_SYS_REG_MDCCINT_EL1 = 0x8010,
HV_SYS_REG_MDSCR_EL1 = 0x8012,
HV_SYS_REG_DBGBVR2_EL1 = 0x8014,
HV_SYS_REG_DBGBCR2_EL1 = 0x8015,
HV_SYS_REG_DBGWVR2_EL1 = 0x8016,
HV_SYS_REG_DBGWCR2_EL1 = 0x8017,
HV_SYS_REG_DBGBVR3_EL1 = 0x801c,
HV_SYS_REG_DBGBCR3_EL1 = 0x801d,
HV_SYS_REG_DBGWVR3_EL1 = 0x801e,
HV_SYS_REG_DBGWCR3_EL1 = 0x801f,
HV_SYS_REG_DBGBVR4_EL1 = 0x8024,
HV_SYS_REG_DBGBCR4_EL1 = 0x8025,
HV_SYS_REG_DBGWVR4_EL1 = 0x8026,
HV_SYS_REG_DBGWCR4_EL1 = 0x8027,
HV_SYS_REG_DBGBVR5_EL1 = 0x802c,
HV_SYS_REG_DBGBCR5_EL1 = 0x802d,
HV_SYS_REG_DBGWVR5_EL1 = 0x802e,
HV_SYS_REG_DBGWCR5_EL1 = 0x802f,
HV_SYS_REG_DBGBVR6_EL1 = 0x8034,
HV_SYS_REG_DBGBCR6_EL1 = 0x8035,
HV_SYS_REG_DBGWVR6_EL1 = 0x8036,
HV_SYS_REG_DBGWCR6_EL1 = 0x8037,
HV_SYS_REG_DBGBVR7_EL1 = 0x803c,
HV_SYS_REG_DBGBCR7_EL1 = 0x803d,
HV_SYS_REG_DBGWVR7_EL1 = 0x803e,
HV_SYS_REG_DBGWCR7_EL1 = 0x803f,
HV_SYS_REG_DBGBVR8_EL1 = 0x8044,
HV_SYS_REG_DBGBCR8_EL1 = 0x8045,
HV_SYS_REG_DBGWVR8_EL1 = 0x8046,
HV_SYS_REG_DBGWCR8_EL1 = 0x8047,
HV_SYS_REG_DBGBVR9_EL1 = 0x804c,
HV_SYS_REG_DBGBCR9_EL1 = 0x804d,
HV_SYS_REG_DBGWVR9_EL1 = 0x804e,
HV_SYS_REG_DBGWCR9_EL1 = 0x804f,
HV_SYS_REG_DBGBVR10_EL1 = 0x8054,
HV_SYS_REG_DBGBCR10_EL1 = 0x8055,
HV_SYS_REG_DBGWVR10_EL1 = 0x8056,
HV_SYS_REG_DBGWCR10_EL1 = 0x8057,
HV_SYS_REG_DBGBVR11_EL1 = 0x805c,
HV_SYS_REG_DBGBCR11_EL1 = 0x805d,
HV_SYS_REG_DBGWVR11_EL1 = 0x805e,
HV_SYS_REG_DBGWCR11_EL1 = 0x805f,
HV_SYS_REG_DBGBVR12_EL1 = 0x8064,
HV_SYS_REG_DBGBCR12_EL1 = 0x8065,
HV_SYS_REG_DBGWVR12_EL1 = 0x8066,
HV_SYS_REG_DBGWCR12_EL1 = 0x8067,
HV_SYS_REG_DBGBVR13_EL1 = 0x806c,
HV_SYS_REG_DBGBCR13_EL1 = 0x806d,
HV_SYS_REG_DBGWVR13_EL1 = 0x806e,
HV_SYS_REG_DBGWCR13_EL1 = 0x806f,
HV_SYS_REG_DBGBVR14_EL1 = 0x8074,
HV_SYS_REG_DBGBCR14_EL1 = 0x8075,
HV_SYS_REG_DBGWVR14_EL1 = 0x8076,
HV_SYS_REG_DBGWCR14_EL1 = 0x8077,
HV_SYS_REG_DBGBVR15_EL1 = 0x807c,
HV_SYS_REG_DBGBCR15_EL1 = 0x807d,
HV_SYS_REG_DBGWVR15_EL1 = 0x807e,
HV_SYS_REG_DBGWCR15_EL1 = 0x807f,
HV_SYS_REG_MIDR_EL1 = 0xc000,
HV_SYS_REG_MPIDR_EL1 = 0xc005,
HV_SYS_REG_ID_AA64PFR0_EL1 = 0xc020,
HV_SYS_REG_ID_AA64PFR1_EL1 = 0xc021,
HV_SYS_REG_ID_AA64DFR0_EL1 = 0xc028,
HV_SYS_REG_ID_AA64DFR1_EL1 = 0xc029,
HV_SYS_REG_ID_AA64ISAR0_EL1 = 0xc030,
HV_SYS_REG_ID_AA64ISAR1_EL1 = 0xc031,
HV_SYS_REG_ID_AA64MMFR0_EL1 = 0xc038,
HV_SYS_REG_ID_AA64MMFR1_EL1 = 0xc039,
HV_SYS_REG_ID_AA64MMFR2_EL1 = 0xc03a,
HV_SYS_REG_SCTLR_EL1 = 0xc080,
HV_SYS_REG_CPACR_EL1 = 0xc082,
HV_SYS_REG_TTBR0_EL1 = 0xc100,
HV_SYS_REG_TTBR1_EL1 = 0xc101,
HV_SYS_REG_TCR_EL1 = 0xc102,
HV_SYS_REG_APIAKEYLO_EL1 = 0xc108,
HV_SYS_REG_APIAKEYHI_EL1 = 0xc109,
HV_SYS_REG_APIBKEYLO_EL1 = 0xc10a,
HV_SYS_REG_APIBKEYHI_EL1 = 0xc10b,
HV_SYS_REG_APDAKEYLO_EL1 = 0xc110,
HV_SYS_REG_APDAKEYHI_EL1 = 0xc111,
HV_SYS_REG_APDBKEYLO_EL1 = 0xc112,
HV_SYS_REG_APDBKEYHI_EL1 = 0xc113,
HV_SYS_REG_APGAKEYLO_EL1 = 0xc118,
HV_SYS_REG_APGAKEYHI_EL1 = 0xc119,
HV_SYS_REG_SPSR_EL1 = 0xc200,
HV_SYS_REG_ELR_EL1 = 0xc201,
HV_SYS_REG_SP_EL0 = 0xc208,
HV_SYS_REG_AFSR0_EL1 = 0xc288,
HV_SYS_REG_AFSR1_EL1 = 0xc289,
HV_SYS_REG_ESR_EL1 = 0xc290,
HV_SYS_REG_FAR_EL1 = 0xc300,
HV_SYS_REG_PAR_EL1 = 0xc3a0,
HV_SYS_REG_MAIR_EL1 = 0xc510,
HV_SYS_REG_AMAIR_EL1 = 0xc518,
HV_SYS_REG_VBAR_EL1 = 0xc600,
HV_SYS_REG_CONTEXTIDR_EL1 = 0xc681,
HV_SYS_REG_TPIDR_EL1 = 0xc684,
HV_SYS_REG_CNTKCTL_EL1 = 0xc708,
HV_SYS_REG_CSSELR_EL1 = 0xd000,
HV_SYS_REG_TPIDR_EL0 = 0xde82,
HV_SYS_REG_TPIDRRO_EL0 = 0xde83,
HV_SYS_REG_CNTV_CTL_EL0 = 0xdf19,
HV_SYS_REG_CNTV_CVAL_EL0 = 0xdf1a,
HV_SYS_REG_SP_EL1 = 0xe208,
DBGBVR0_EL1 = 0x8004,
DBGBCR0_EL1 = 0x8005,
DBGWVR0_EL1 = 0x8006,
DBGWCR0_EL1 = 0x8007,
DBGBVR1_EL1 = 0x800c,
DBGBCR1_EL1 = 0x800d,
DBGWVR1_EL1 = 0x800e,
DBGWCR1_EL1 = 0x800f,
MDCCINT_EL1 = 0x8010,
MDSCR_EL1 = 0x8012,
DBGBVR2_EL1 = 0x8014,
DBGBCR2_EL1 = 0x8015,
DBGWVR2_EL1 = 0x8016,
DBGWCR2_EL1 = 0x8017,
DBGBVR3_EL1 = 0x801c,
DBGBCR3_EL1 = 0x801d,
DBGWVR3_EL1 = 0x801e,
DBGWCR3_EL1 = 0x801f,
DBGBVR4_EL1 = 0x8024,
DBGBCR4_EL1 = 0x8025,
DBGWVR4_EL1 = 0x8026,
DBGWCR4_EL1 = 0x8027,
DBGBVR5_EL1 = 0x802c,
DBGBCR5_EL1 = 0x802d,
DBGWVR5_EL1 = 0x802e,
DBGWCR5_EL1 = 0x802f,
DBGBVR6_EL1 = 0x8034,
DBGBCR6_EL1 = 0x8035,
DBGWVR6_EL1 = 0x8036,
DBGWCR6_EL1 = 0x8037,
DBGBVR7_EL1 = 0x803c,
DBGBCR7_EL1 = 0x803d,
DBGWVR7_EL1 = 0x803e,
DBGWCR7_EL1 = 0x803f,
DBGBVR8_EL1 = 0x8044,
DBGBCR8_EL1 = 0x8045,
DBGWVR8_EL1 = 0x8046,
DBGWCR8_EL1 = 0x8047,
DBGBVR9_EL1 = 0x804c,
DBGBCR9_EL1 = 0x804d,
DBGWVR9_EL1 = 0x804e,
DBGWCR9_EL1 = 0x804f,
DBGBVR10_EL1 = 0x8054,
DBGBCR10_EL1 = 0x8055,
DBGWVR10_EL1 = 0x8056,
DBGWCR10_EL1 = 0x8057,
DBGBVR11_EL1 = 0x805c,
DBGBCR11_EL1 = 0x805d,
DBGWVR11_EL1 = 0x805e,
DBGWCR11_EL1 = 0x805f,
DBGBVR12_EL1 = 0x8064,
DBGBCR12_EL1 = 0x8065,
DBGWVR12_EL1 = 0x8066,
DBGWCR12_EL1 = 0x8067,
DBGBVR13_EL1 = 0x806c,
DBGBCR13_EL1 = 0x806d,
DBGWVR13_EL1 = 0x806e,
DBGWCR13_EL1 = 0x806f,
DBGBVR14_EL1 = 0x8074,
DBGBCR14_EL1 = 0x8075,
DBGWVR14_EL1 = 0x8076,
DBGWCR14_EL1 = 0x8077,
DBGBVR15_EL1 = 0x807c,
DBGBCR15_EL1 = 0x807d,
DBGWVR15_EL1 = 0x807e,
DBGWCR15_EL1 = 0x807f,
MIDR_EL1 = 0xc000,
MPIDR_EL1 = 0xc005,
ID_AA64PFR0_EL1 = 0xc020,
ID_AA64PFR1_EL1 = 0xc021,
ID_AA64DFR0_EL1 = 0xc028,
ID_AA64DFR1_EL1 = 0xc029,
ID_AA64ISAR0_EL1 = 0xc030,
ID_AA64ISAR1_EL1 = 0xc031,
ID_AA64MMFR0_EL1 = 0xc038,
ID_AA64MMFR1_EL1 = 0xc039,
ID_AA64MMFR2_EL1 = 0xc03a,
SCTLR_EL1 = 0xc080,
CPACR_EL1 = 0xc082,
TTBR0_EL1 = 0xc100,
TTBR1_EL1 = 0xc101,
TCR_EL1 = 0xc102,
APIAKEYLO_EL1 = 0xc108,
APIAKEYHI_EL1 = 0xc109,
APIBKEYLO_EL1 = 0xc10a,
APIBKEYHI_EL1 = 0xc10b,
APDAKEYLO_EL1 = 0xc110,
APDAKEYHI_EL1 = 0xc111,
APDBKEYLO_EL1 = 0xc112,
APDBKEYHI_EL1 = 0xc113,
APGAKEYLO_EL1 = 0xc118,
APGAKEYHI_EL1 = 0xc119,
SPSR_EL1 = 0xc200,
ELR_EL1 = 0xc201,
SP_EL0 = 0xc208,
AFSR0_EL1 = 0xc288,
AFSR1_EL1 = 0xc289,
ESR_EL1 = 0xc290,
FAR_EL1 = 0xc300,
PAR_EL1 = 0xc3a0,
MAIR_EL1 = 0xc510,
AMAIR_EL1 = 0xc518,
VBAR_EL1 = 0xc600,
CONTEXTIDR_EL1 = 0xc681,
TPIDR_EL1 = 0xc684,
CNTKCTL_EL1 = 0xc708,
CSSELR_EL1 = 0xd000,
TPIDR_EL0 = 0xde82,
TPIDRRO_EL0 = 0xde83,
CNTV_CTL_EL0 = 0xdf19,
CNTV_CVAL_EL0 = 0xdf1a,
SP_EL1 = 0xe208,
}
enum hv_memory_flags_t : ulong
enum HvMemoryFlags : ulong
{
HV_MEMORY_READ = 1UL << 0,
HV_MEMORY_WRITE = 1UL << 1,
HV_MEMORY_EXEC = 1UL << 2
Read = 1UL << 0,
Write = 1UL << 1,
Exec = 1UL << 2,
}
enum hv_result_t : uint
enum HvResult : uint
{
HV_SUCCESS = 0,
HV_ERROR = 0xfae94001,
HV_BUSY = 0xfae94002,
HV_BAD_ARGUMENT = 0xfae94003,
HV_NO_RESOURCES = 0xfae94005,
HV_NO_DEVICE = 0xfae94006,
HV_DENIED = 0xfae94007,
HV_UNSUPPORTED = 0xfae9400f
Success = 0,
Error = 0xfae94001,
Busy = 0xfae94002,
BadArgument = 0xfae94003,
NoResources = 0xfae94005,
NoDevice = 0xfae94006,
Denied = 0xfae94007,
Unsupported = 0xfae9400f,
}
enum hv_interrupt_type_t : uint
enum HvInterruptType : uint
{
HV_INTERRUPT_TYPE_IRQ,
HV_INTERRUPT_TYPE_FIQ
IRQ,
FIQ,
}
struct hv_simd_fp_uchar16_t
struct HvSimdFPUchar16
{
public ulong Low;
public ulong High;
@@ -247,9 +246,9 @@ namespace Ryujinx.Cpu.AppleHv
static class HvResultExtensions
{
public static void ThrowOnError(this hv_result_t result)
public static void ThrowOnError(this HvResult result)
{
if (result != hv_result_t.HV_SUCCESS)
if (result != HvResult.Success)
{
throw new Exception($"Unexpected result \"{result}\".");
}
@@ -261,60 +260,60 @@ namespace Ryujinx.Cpu.AppleHv
public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
public static partial HvResult hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_create(IntPtr config);
public static partial HvResult hv_vm_create(IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_destroy();
public static partial HvResult hv_vm_destroy();
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_map(ulong addr, ulong ipa, ulong size, hv_memory_flags_t flags);
public static partial HvResult hv_vm_map(ulong addr, ulong ipa, ulong size, HvMemoryFlags flags);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_unmap(ulong ipa, ulong size);
public static partial HvResult hv_vm_unmap(ulong ipa, ulong size);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vm_protect(ulong ipa, ulong size, hv_memory_flags_t flags);
public static partial HvResult hv_vm_protect(ulong ipa, ulong size, HvMemoryFlags flags);
[LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_create(out ulong vcpu, ref hv_vcpu_exit_t* exit, IntPtr config);
public unsafe static partial HvResult hv_vcpu_create(out ulong vcpu, ref HvVcpuExit* exit, IntPtr config);
[LibraryImport(LibraryName, SetLastError = true)]
public unsafe static partial hv_result_t hv_vcpu_destroy(ulong vcpu);
public unsafe static partial HvResult hv_vcpu_destroy(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_run(ulong vcpu);
public static partial HvResult hv_vcpu_run(ulong vcpu);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
public static partial HvResult hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
public static partial HvResult hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_reg(ulong vcpu, hv_reg_t reg, out ulong value);
public static partial HvResult hv_vcpu_get_reg(ulong vcpu, HvReg reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_reg(ulong vcpu, hv_reg_t reg, ulong value);
public static partial HvResult hv_vcpu_set_reg(ulong vcpu, HvReg reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, out hv_simd_fp_uchar16_t value);
public static partial HvResult hv_vcpu_get_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, out HvSimdFPUchar16 value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, hv_simd_fp_uchar16_t value); // DO NOT USE DIRECTLY!
public static partial HvResult hv_vcpu_set_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, HvSimdFPUchar16 value); // DO NOT USE DIRECTLY!
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_sys_reg(ulong vcpu, hv_sys_reg_t reg, out ulong value);
public static partial HvResult hv_vcpu_get_sys_reg(ulong vcpu, HvSysReg reg, out ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_sys_reg(ulong vcpu, hv_sys_reg_t reg, ulong value);
public static partial HvResult hv_vcpu_set_sys_reg(ulong vcpu, HvSysReg reg, ulong value);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_get_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
public static partial HvResult hv_vcpu_get_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
[LibraryImport(LibraryName, SetLastError = true)]
public static partial hv_result_t hv_vcpu_set_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] bool pending);
public static partial HvResult hv_vcpu_set_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] bool pending);
}
}
}

View File

@@ -1,5 +1,4 @@
using ARMeilleure.Memory;
using System;
namespace Ryujinx.Cpu.AppleHv
{
@@ -14,10 +13,6 @@ namespace Ryujinx.Cpu.AppleHv
_memoryManager = (HvMemoryManager)memory;
}
private void UnmapHandler(ulong address, ulong size)
{
}
/// <inheritdoc/>
public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks)
{
@@ -44,4 +39,4 @@ namespace Ryujinx.Cpu.AppleHv
{
}
}
}
}

View File

@@ -17,4 +17,4 @@ namespace Ryujinx.Cpu.AppleHv
return new HvCpuContext(_tickSource, memoryManager, for64Bit);
}
}
}
}

View File

@@ -125,17 +125,17 @@ namespace Ryujinx.Cpu.AppleHv
{
HvVcpu vcpu = HvVcpuPool.Instance.Create(memoryManager.AddressSpace, _shadowContext, SwapContext);
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError();
HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
while (Running)
{
HvApi.hv_vcpu_run(vcpu.Handle).ThrowOnError();
uint reason = vcpu.ExitInfo->reason;
uint reason = vcpu.ExitInfo->Reason;
if (reason == 1)
{
uint hvEsr = (uint)vcpu.ExitInfo->exception.syndrome;
uint hvEsr = (uint)vcpu.ExitInfo->Exception.Syndrome;
ExceptionClass hvEc = (ExceptionClass)(hvEsr >> 26);
if (hvEc != ExceptionClass.HvcAarch64)
@@ -144,7 +144,7 @@ namespace Ryujinx.Cpu.AppleHv
}
address = SynchronousException(memoryManager, ref vcpu);
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError();
HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
}
else if (reason == 0)
{
@@ -168,8 +168,8 @@ namespace Ryujinx.Cpu.AppleHv
{
ulong vcpuHandle = vcpu.Handle;
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
ExceptionClass ec = (ExceptionClass)((uint)esr >> 26);
@@ -180,7 +180,7 @@ namespace Ryujinx.Cpu.AppleHv
break;
case ExceptionClass.TrappedMsrMrsSystem:
InstructionTrap((uint)esr);
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, elr + 4UL).ThrowOnError();
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, elr + 4UL).ThrowOnError();
break;
case ExceptionClass.SvcAarch64:
ReturnToPool(vcpu);
@@ -204,7 +204,7 @@ namespace Ryujinx.Cpu.AppleHv
}
}
private void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr)
private static void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr)
{
bool write = (esr & (1u << 6)) != 0;
bool farValid = (esr & (1u << 10)) == 0;
@@ -212,7 +212,7 @@ namespace Ryujinx.Cpu.AppleHv
if (farValid)
{
HvApi.hv_vcpu_get_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_FAR_EL1, out ulong far).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(vcpu, HvSysReg.FAR_EL1, out ulong far).ThrowOnError();
ulong size = 1UL << accessSizeLog2;
@@ -281,4 +281,4 @@ namespace Ryujinx.Cpu.AppleHv
{
}
}
}
}

View File

@@ -2,7 +2,7 @@ using ARMeilleure.State;
namespace Ryujinx.Cpu.AppleHv
{
unsafe class HvExecutionContextShadow : IHvExecutionContext
class HvExecutionContextShadow : IHvExecutionContext
{
public ulong Pc { get; set; }
public ulong ElrEl1 { get; set; }
@@ -56,4 +56,4 @@ namespace Ryujinx.Cpu.AppleHv
return false;
}
}
}
}

View File

@@ -8,10 +8,10 @@ namespace Ryujinx.Cpu.AppleHv
{
class HvExecutionContextVcpu : IHvExecutionContext
{
private static MemoryBlock _setSimdFpRegFuncMem;
private delegate hv_result_t SetSimdFpReg(ulong vcpu, hv_simd_fp_reg_t reg, in V128 value, IntPtr funcPtr);
private static SetSimdFpReg _setSimdFpReg;
private static IntPtr _setSimdFpRegNativePtr;
private static readonly MemoryBlock _setSimdFpRegFuncMem;
private delegate HvResult SetSimdFpReg(ulong vcpu, HvSimdFPReg reg, in V128 value, IntPtr funcPtr);
private static readonly SetSimdFpReg _setSimdFpReg;
private static readonly IntPtr _setSimdFpRegNativePtr;
static HvExecutionContextVcpu()
{
@@ -34,12 +34,12 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_PC, out ulong pc).ThrowOnError();
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.PC, out ulong pc).ThrowOnError();
return pc;
}
set
{
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_PC, value).ThrowOnError();
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.PC, value).ThrowOnError();
}
}
@@ -47,12 +47,12 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
return elr;
}
set
{
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, value).ThrowOnError();
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ELR_EL1, value).ThrowOnError();
}
}
@@ -60,12 +60,12 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
return esr;
}
set
{
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, value).ThrowOnError();
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ESR_EL1, value).ThrowOnError();
}
}
@@ -73,12 +73,12 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, out ulong tpidrEl0).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, out ulong tpidrEl0).ThrowOnError();
return (long)tpidrEl0;
}
set
{
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, (ulong)value).ThrowOnError();
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, (ulong)value).ThrowOnError();
}
}
@@ -86,12 +86,12 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError();
return (long)tpidrroEl0;
}
set
{
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, (ulong)value).ThrowOnError();
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, (ulong)value).ThrowOnError();
}
}
@@ -99,12 +99,12 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_CPSR, out ulong cpsr).ThrowOnError();
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong cpsr).ThrowOnError();
return (uint)cpsr;
}
set
{
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_CPSR, (ulong)value).ThrowOnError();
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, (ulong)value).ThrowOnError();
}
}
@@ -112,12 +112,12 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPCR, out ulong fpcr).ThrowOnError();
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPCR, out ulong fpcr).ThrowOnError();
return (uint)fpcr;
}
set
{
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPCR, (ulong)value).ThrowOnError();
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPCR, (ulong)value).ThrowOnError();
}
}
@@ -125,16 +125,16 @@ namespace Ryujinx.Cpu.AppleHv
{
get
{
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPSR, out ulong fpsr).ThrowOnError();
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPSR, out ulong fpsr).ThrowOnError();
return (uint)fpsr;
}
set
{
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPSR, (ulong)value).ThrowOnError();
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPSR, (ulong)value).ThrowOnError();
}
}
private ulong _vcpu;
private readonly ulong _vcpu;
private int _interruptRequested;
public HvExecutionContextVcpu(ulong vcpu)
@@ -146,12 +146,12 @@ namespace Ryujinx.Cpu.AppleHv
{
if (index == 31)
{
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, out ulong value).ThrowOnError();
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.SP_EL0, out ulong value).ThrowOnError();
return value;
}
else
{
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, out ulong value).ThrowOnError();
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.X0 + (uint)index, out ulong value).ThrowOnError();
return value;
}
}
@@ -160,23 +160,23 @@ namespace Ryujinx.Cpu.AppleHv
{
if (index == 31)
{
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, value).ThrowOnError();
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.SP_EL0, value).ThrowOnError();
}
else
{
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, value).ThrowOnError();
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.X0 + (uint)index, value).ThrowOnError();
}
}
public V128 GetV(int index)
{
HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, out hv_simd_fp_uchar16_t value).ThrowOnError();
HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, HvSimdFPReg.Q0 + (uint)index, out HvSimdFPUchar16 value).ThrowOnError();
return new V128(value.Low, value.High);
}
public void SetV(int index, V128 value)
{
_setSimdFpReg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError();
_setSimdFpReg(_vcpu, HvSimdFPReg.Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError();
}
public void RequestInterrupt()
@@ -193,4 +193,4 @@ namespace Ryujinx.Cpu.AppleHv
return Interlocked.Exchange(ref _interruptRequested, 0) != 0;
}
}
}
}

View File

@@ -31,4 +31,4 @@ namespace Ryujinx.Cpu.AppleHv
_block.Free(offset, size);
}
}
}
}

View File

@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Cpu.AppleHv
{
struct HvMemoryBlockAllocation : IDisposable
readonly struct HvMemoryBlockAllocation : IDisposable
{
private readonly HvMemoryBlockAllocator _owner;
private readonly HvMemoryBlockAllocator.Block _block;

View File

@@ -1,12 +1,9 @@
using Ryujinx.Memory;
using System.Collections.Generic;
namespace Ryujinx.Cpu.AppleHv
{
class HvMemoryBlockAllocator : PrivateMemoryAllocatorImpl<HvMemoryBlockAllocator.Block>
{
private const ulong InvalidOffset = ulong.MaxValue;
public class Block : PrivateMemoryAllocator.Block
{
private readonly HvIpaAllocator _ipaAllocator;
@@ -21,7 +18,7 @@ namespace Ryujinx.Cpu.AppleHv
Ipa = ipaAllocator.Allocate(size);
}
HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE).ThrowOnError();
HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, HvMemoryFlags.Read | HvMemoryFlags.Write).ThrowOnError();
}
public override void Destroy()
@@ -44,7 +41,7 @@ namespace Ryujinx.Cpu.AppleHv
_ipaAllocator = ipaAllocator;
}
public unsafe HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
public HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
{
var allocation = Allocate(size, alignment, CreateBlock);

View File

@@ -32,7 +32,7 @@ namespace Ryujinx.Cpu.AppleHv
MappedReplicated = 0x5555555555555555,
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
ReadWriteTrackedReplicated = ulong.MaxValue
ReadWriteTrackedReplicated = ulong.MaxValue,
}
private readonly InvalidAccessHandler _invalidAccessHandler;
@@ -126,6 +126,7 @@ namespace Ryujinx.Cpu.AppleHv
}
}
#pragma warning disable IDE0051 // Remove unused private member
/// <summary>
/// Ensures the combination of virtual address and size is part of the addressable space and fully mapped.
/// </summary>
@@ -138,6 +139,7 @@ namespace Ryujinx.Cpu.AppleHv
throw new InvalidMemoryRegionException($"Not mapped: va=0x{va:X16}, size=0x{size:X16}");
}
}
#pragma warning restore IDE0051
/// <inheritdoc/>
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
@@ -306,7 +308,7 @@ namespace Ryujinx.Cpu.AppleHv
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size));
data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
offset += size;
}
@@ -428,7 +430,7 @@ namespace Ryujinx.Cpu.AppleHv
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
{
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
@@ -606,7 +608,7 @@ namespace Ryujinx.Cpu.AppleHv
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size));
_backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
offset += size;
}
@@ -723,7 +725,7 @@ namespace Ryujinx.Cpu.AppleHv
/// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, ulong size, out ulong startVa)
private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
{
// WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask;
@@ -814,7 +816,7 @@ namespace Ryujinx.Cpu.AppleHv
{
MemoryPermission.None => MemoryPermission.ReadAndWrite,
MemoryPermission.Write => MemoryPermission.Read,
_ => MemoryPermission.None
_ => MemoryPermission.None,
};
_addressSpace.ReprotectUser(va, size, protection);
@@ -943,4 +945,4 @@ namespace Ryujinx.Cpu.AppleHv
private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
}
}
}

View File

@@ -3,14 +3,14 @@ namespace Ryujinx.Cpu.AppleHv
unsafe class HvVcpu
{
public readonly ulong Handle;
public readonly hv_vcpu_exit_t* ExitInfo;
public readonly HvVcpuExit* ExitInfo;
public readonly IHvExecutionContext ShadowContext;
public readonly IHvExecutionContext NativeContext;
public readonly bool IsEphemeral;
public HvVcpu(
ulong handle,
hv_vcpu_exit_t* exitInfo,
HvVcpuExit* exitInfo,
IHvExecutionContext shadowContext,
IHvExecutionContext nativeContext,
bool isEphemeral)
@@ -22,4 +22,4 @@ namespace Ryujinx.Cpu.AppleHv
IsEphemeral = isEphemeral;
}
}
}
}

View File

@@ -17,10 +17,10 @@ namespace Ryujinx.Cpu.AppleHv
private const int MaxActiveVcpus = 4;
public static readonly HvVcpuPool Instance = new HvVcpuPool();
public static readonly HvVcpuPool Instance = new();
private int _totalVcpus;
private int _maxVcpus;
private readonly int _maxVcpus;
public HvVcpuPool()
{
@@ -69,17 +69,17 @@ namespace Ryujinx.Cpu.AppleHv
bool isEphemeral = newCount > _maxVcpus - MaxActiveVcpus;
// Create VCPU.
hv_vcpu_exit_t* exitInfo = null;
HvVcpuExit* exitInfo = null;
HvApi.hv_vcpu_create(out ulong vcpuHandle, ref exitInfo, IntPtr.Zero).ThrowOnError();
// Enable FP and SIMD instructions.
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_CPACR_EL1, 0b11 << 20).ThrowOnError();
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.CPACR_EL1, 0b11 << 20).ThrowOnError();
addressSpace.InitializeMmu(vcpuHandle);
HvExecutionContextVcpu nativeContext = new HvExecutionContextVcpu(vcpuHandle);
HvExecutionContextVcpu nativeContext = new(vcpuHandle);
HvVcpu vcpu = new HvVcpu(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral);
HvVcpu vcpu = new(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral);
return vcpu;
}
@@ -100,4 +100,4 @@ namespace Ryujinx.Cpu.AppleHv
Interlocked.Decrement(ref _totalVcpus);
}
}
}
}

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.Cpu.AppleHv
private static int _addressSpaces;
private static HvIpaAllocator _ipaAllocator;
private static object _lock = new object();
private static readonly object _lock = new();
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
{
@@ -36,7 +36,7 @@ namespace Ryujinx.Cpu.AppleHv
baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
}
var rwx = hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE | hv_memory_flags_t.HV_MEMORY_EXEC;
var rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec;
HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();
@@ -65,4 +65,4 @@ namespace Ryujinx.Cpu.AppleHv
}
}
}
}
}

View File

@@ -43,4 +43,4 @@ namespace Ryujinx.Cpu.AppleHv
void RequestInterrupt();
bool GetAndClearInterruptRequested();
}
}
}

View File

@@ -23,7 +23,7 @@ namespace Ryujinx.Cpu.Jit
PtcLoadingState.Start => LoadState.Unloaded,
PtcLoadingState.Loading => LoadState.Loading,
PtcLoadingState.Loaded => LoadState.Loaded,
_ => throw new ArgumentException($"Invalid load state \"{newState}\".")
_ => throw new ArgumentException($"Invalid load state \"{newState}\"."),
};
StateChanged?.Invoke(state, current, total);
@@ -35,4 +35,4 @@ namespace Ryujinx.Cpu.Jit
_loadState.Continue();
}
}
}
}

View File

@@ -17,4 +17,4 @@ namespace Ryujinx.Cpu.Jit
return new JitCpuContext(_tickSource, memoryManager, for64Bit);
}
}
}
}

View File

@@ -120,4 +120,4 @@ namespace Ryujinx.Cpu.Jit
_impl.Dispose();
}
}
}
}

View File

@@ -19,6 +19,10 @@ namespace Ryujinx.Cpu.Jit
public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute);
public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute);
public void Dispose() => _impl.Dispose();
public void Dispose()
{
GC.SuppressFinalize(this);
_impl.Dispose();
}
}
}
}

View File

@@ -84,7 +84,6 @@ namespace Ryujinx.Cpu.Jit
ulong remainingSize = size;
ulong oVa = va;
ulong oPa = pa;
while (remainingSize != 0)
{
_pageTable.Write((va / PageSize) * PteSize, PaToPte(pa));
@@ -246,7 +245,7 @@ namespace Ryujinx.Cpu.Jit
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size));
data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
offset += size;
}
@@ -298,7 +297,7 @@ namespace Ryujinx.Cpu.Jit
}
/// <inheritdoc/>
public unsafe WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false)
public WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false)
{
if (size == 0)
{
@@ -345,7 +344,7 @@ namespace Ryujinx.Cpu.Jit
/// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, uint size, out ulong startVa)
private static int GetPagesCount(ulong va, uint size, out ulong startVa)
{
// WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask;
@@ -482,7 +481,7 @@ namespace Ryujinx.Cpu.Jit
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size));
_backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
offset += size;
}
@@ -576,6 +575,7 @@ namespace Ryujinx.Cpu.Jit
}
}
#pragma warning disable IDE0051 // Remove unused private member
private ulong GetPhysicalAddress(ulong va)
{
// We return -1L if the virtual address is invalid or unmapped.
@@ -586,6 +586,7 @@ namespace Ryujinx.Cpu.Jit
return GetPhysicalAddressInternal(va);
}
#pragma warning restore IDE0051
private ulong GetPhysicalAddressInternal(ulong va)
{
@@ -604,7 +605,7 @@ namespace Ryujinx.Cpu.Jit
{
MemoryPermission.None => 0L,
MemoryPermission.Write => 2L << PointerTagBit,
_ => 3L << PointerTagBit
_ => 3L << PointerTagBit,
};
int pages = GetPagesCount(va, (uint)size, out va);
@@ -698,6 +699,8 @@ namespace Ryujinx.Cpu.Jit
/// </summary>
protected override void Destroy() => _pageTable.Dispose();
private void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
#pragma warning disable IDE0051 // Remove unused private member
private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
#pragma warning restore IDE0051
}
}

View File

@@ -31,7 +31,7 @@ namespace Ryujinx.Cpu.Jit
MappedReplicated = 0x5555555555555555,
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
ReadWriteTrackedReplicated = ulong.MaxValue
ReadWriteTrackedReplicated = ulong.MaxValue,
}
private readonly InvalidAccessHandler _invalidAccessHandler;
@@ -404,7 +404,7 @@ namespace Ryujinx.Cpu.Jit
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
{
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
@@ -606,7 +606,7 @@ namespace Ryujinx.Cpu.Jit
/// <param name="startVa">The virtual address of the beginning of the first page</param>
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetPagesCount(ulong va, ulong size, out ulong startVa)
private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
{
// WARNING: Always check if ulong does not overflow during the operations.
startVa = va & ~(ulong)PageMask;
@@ -697,7 +697,7 @@ namespace Ryujinx.Cpu.Jit
{
MemoryPermission.None => MemoryPermission.ReadAndWrite,
MemoryPermission.Write => MemoryPermission.Read,
_ => MemoryPermission.None
_ => MemoryPermission.None,
};
_addressSpace.Base.Reprotect(va, size, protection, false);

View File

@@ -7,6 +7,6 @@ namespace Ryujinx.Cpu
{
Unloaded,
Loading,
Loaded
Loaded,
}
}
}

View File

@@ -10,7 +10,6 @@ namespace Ryujinx.Cpu
{
private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write);
private readonly MemoryTracking _tracking;
private readonly TrackingEventDelegate _trackingEvent;
private readonly ulong _baseAddress;
@@ -18,12 +17,10 @@ namespace Ryujinx.Cpu
public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
{
_tracking = tracking;
_baseAddress = (ulong)addressSpace.Pointer;
ulong endAddress = _baseAddress + addressSpace.Size;
_trackingEvent = new TrackingEventDelegate(tracking.VirtualMemoryEvent);
_trackingEvent = tracking.VirtualMemoryEvent;
bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
if (!added)
@@ -51,6 +48,8 @@ namespace Ryujinx.Cpu
public void Dispose()
{
GC.SuppressFinalize(this);
NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress);
if (_mirrorAddress != 0)

View File

@@ -2,7 +2,6 @@
using Ryujinx.Common.Memory;
using Ryujinx.Memory;
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@@ -26,12 +25,12 @@ namespace Ryujinx.Cpu
}
}
public unsafe static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged
public static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged
{
return MemoryMarshal.Cast<byte, T>(memory.GetSpan(position, Unsafe.SizeOf<T>()))[0];
}
public unsafe static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged
public static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged
{
ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1));
@@ -42,22 +41,21 @@ namespace Ryujinx.Cpu
public static string ReadAsciiString(IVirtualMemoryManager memory, ulong position, long maxSize = -1)
{
using (RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream())
using RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream();
for (long offs = 0; offs < maxSize || maxSize == -1; offs++)
{
for (long offs = 0; offs < maxSize || maxSize == -1; offs++)
byte value = memory.Read<byte>(position + (ulong)offs);
if (value == 0)
{
byte value = memory.Read<byte>(position + (ulong)offs);
if (value == 0)
{
break;
}
ms.WriteByte(value);
break;
}
return Encoding.ASCII.GetString(ms.GetReadOnlySequence());
ms.WriteByte(value);
}
return Encoding.ASCII.GetString(ms.GetReadOnlySequence());
}
}
}
}

View File

@@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Cpu
{
struct PrivateMemoryAllocation : IDisposable
readonly struct PrivateMemoryAllocation : IDisposable
{
private readonly PrivateMemoryAllocator _owner;
private readonly PrivateMemoryAllocator.Block _block;
@@ -27,8 +27,8 @@ namespace Ryujinx.Cpu
public (PrivateMemoryAllocation, PrivateMemoryAllocation) Split(ulong splitOffset)
{
PrivateMemoryAllocation left = new PrivateMemoryAllocation(_owner, _block, Offset, splitOffset);
PrivateMemoryAllocation right = new PrivateMemoryAllocation(_owner, _block, Offset + splitOffset, Size - splitOffset);
PrivateMemoryAllocation left = new(_owner, _block, Offset, splitOffset);
PrivateMemoryAllocation right = new(_owner, _block, Offset + splitOffset, Size - splitOffset);
return (left, right);
}

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Cpu
public MemoryBlock Memory { get; private set; }
public ulong Size { get; }
private struct Range : IComparable<Range>
private readonly struct Range : IComparable<Range>
{
public ulong Offset { get; }
public ulong Size { get; }
@@ -40,7 +40,7 @@ namespace Ryujinx.Cpu
Size = size;
_freeRanges = new List<Range>
{
new Range(0, size)
new Range(0, size),
};
}
@@ -164,7 +164,7 @@ namespace Ryujinx.Cpu
{
private const ulong InvalidOffset = ulong.MaxValue;
public struct Allocation
public readonly struct Allocation
{
public T Block { get; }
public ulong Offset { get; }
@@ -265,4 +265,4 @@ namespace Ryujinx.Cpu
_blocks.Clear();
}
}
}
}

View File

@@ -42,4 +42,4 @@ namespace Ryujinx.Cpu
_tickCounter.Start();
}
}
}
}

View File

@@ -1,14 +1,7 @@
using NUnit.Framework;
using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Server.Upsampler;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Ryujinx.Tests.Audio.Renderer.Dsp
{
@@ -41,8 +34,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
/// <param name="quality">The resampler quality to use</param>
private static void DoResamplingTest(int inputRate, int outputRate, VoiceInParameter.SampleRateConversionQuality quality)
{
float inputSampleRate = (float)inputRate;
float outputSampleRate = (float)outputRate;
float inputSampleRate = inputRate;
float outputSampleRate = outputRate;
int inputSampleCount = inputRate;
int outputSampleCount = outputRate;
short[] inputBuffer = new short[inputSampleCount + 100]; // add some safety buffer at the end
@@ -50,7 +43,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
for (int sample = 0; sample < inputBuffer.Length; sample++)
{
// 440 hz sine wave with amplitude = 0.5f at input sample rate
inputBuffer[sample] = (short)(32767 * MathF.Sin((440 / inputSampleRate) * (float)sample * MathF.PI * 2f) * 0.5f);
inputBuffer[sample] = (short)(32767 * MathF.Sin((440 / inputSampleRate) * sample * MathF.PI * 2f) * 0.5f);
}
float fraction = 0;
@@ -70,14 +63,14 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
{
VoiceInParameter.SampleRateConversionQuality.High => 3,
VoiceInParameter.SampleRateConversionQuality.Default => 1,
_ => 0
_ => 0,
};
for (int sample = 0; sample < outputSampleCount; sample++)
{
outputBuffer[sample] /= 32767;
// 440 hz sine wave with amplitude = 0.5f at output sample rate
expectedOutput[sample] = MathF.Sin((440 / outputSampleRate) * (float)(sample + delay) * MathF.PI * 2f) * 0.5f;
expectedOutput[sample] = MathF.Sin((440 / outputSampleRate) * (sample + delay) * MathF.PI * 2f) * 0.5f;
float thisDelta = Math.Abs(expectedOutput[sample] - outputBuffer[sample]);
// Ensure no discontinuities
@@ -85,7 +78,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
sumDifference += thisDelta;
}
sumDifference = sumDifference / (float)outputSampleCount;
sumDifference /= outputSampleCount;
// Expect the output to be 99% similar to the expected resampled sine wave
Assert.IsTrue(sumDifference < 0.01f);
}

View File

@@ -1,14 +1,7 @@
using NUnit.Framework;
using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Server.Upsampler;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Ryujinx.Tests.Audio.Renderer.Dsp
{
@@ -17,7 +10,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
[Test]
public void TestUpsamplerConsistency()
{
UpsamplerBufferState bufferState = new UpsamplerBufferState();
UpsamplerBufferState bufferState = new();
int inputBlockSize = 160;
int numInputSamples = 32000;
int numOutputSamples = 48000;
@@ -28,14 +21,14 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
for (int sample = 0; sample < inputBuffer.Length; sample++)
{
// 440 hz sine wave with amplitude = 0.5f at input sample rate
inputBuffer[sample] = MathF.Sin((440 / inputSampleRate) * (float)sample * MathF.PI * 2f) * 0.5f;
inputBuffer[sample] = MathF.Sin((440 / inputSampleRate) * sample * MathF.PI * 2f) * 0.5f;
}
int inputIdx = 0;
int outputIdx = 0;
while (inputIdx + inputBlockSize < numInputSamples)
{
int outputBufLength = (int)Math.Round((float)(inputIdx + inputBlockSize) * outputSampleRate / inputSampleRate) - outputIdx;
int outputBufLength = (int)Math.Round((inputIdx + inputBlockSize) * outputSampleRate / inputSampleRate) - outputIdx;
UpsamplerHelper.Upsample(
outputBuffer.AsSpan(outputIdx),
inputBuffer.AsSpan(inputIdx),
@@ -52,11 +45,11 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
for (int sample = 0; sample < numOutputSamples; sample++)
{
// 440 hz sine wave with amplitude = 0.5f at output sample rate with an offset of 15
expectedOutput[sample] = MathF.Sin((440 / outputSampleRate) * (float)(sample - 15) * MathF.PI * 2f) * 0.5f;
expectedOutput[sample] = MathF.Sin((440 / outputSampleRate) * (sample - 15) * MathF.PI * 2f) * 0.5f;
sumDifference += Math.Abs(expectedOutput[sample] - outputBuffer[sample]);
}
sumDifference = sumDifference / (float)expectedOutput.Length;
sumDifference /= expectedOutput.Length;
// Expect the output to be 98% similar to the expected resampled sine wave
Assert.IsTrue(sumDifference < 0.02f);
}

View File

@@ -13,4 +13,3 @@ namespace Ryujinx.Tests.Audio.Renderer.Parameter.Effect
}
}
}

View File

@@ -13,4 +13,3 @@ namespace Ryujinx.Tests.Audio.Renderer.Parameter.Effect
}
}
}

View File

@@ -13,4 +13,3 @@ namespace Ryujinx.Tests.Audio.Renderer.Parameter.Effect
}
}
}

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestCheckFeature()
{
int latestRevision = BehaviourContext.BaseRevisionMagic + BehaviourContext.LastRevision;
int latestRevision = BehaviourContext.BaseRevisionMagic + BehaviourContext.LastRevision;
int previousRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision - 1);
int invalidRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision + 1);
@@ -22,7 +22,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestsMemoryPoolForceMappingEnabled()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
@@ -36,7 +36,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision1()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
@@ -62,7 +62,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision2()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision2);
@@ -88,7 +88,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision3()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision3);
@@ -114,7 +114,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision4()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision4);
@@ -140,7 +140,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision5()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision5);
@@ -166,7 +166,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision6()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision6);
@@ -192,7 +192,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision7()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision7);
@@ -218,7 +218,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision8()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision8);
@@ -244,7 +244,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision9()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision9);
@@ -270,7 +270,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestRevision10()
{
BehaviourContext behaviourContext = new BehaviourContext();
BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision10);
@@ -293,4 +293,4 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
}
}
}
}

View File

@@ -15,13 +15,13 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestInitializeSystemPool()
{
PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true);
PoolMapper poolMapper = new(DummyProcessHandle, true);
MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
const ulong CpuSize = 0x1000;
const ulong CpuSize = 0x1000;
Assert.IsFalse(poolMapper.InitializeSystemPool(ref memoryPoolCpu, CpuAddress, CpuSize));
Assert.IsTrue(poolMapper.InitializeSystemPool(ref memoryPoolDsp, CpuAddress, CpuSize));
@@ -34,7 +34,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestGetProcessHandle()
{
PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true);
PoolMapper poolMapper = new(DummyProcessHandle, true);
MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
@@ -45,13 +45,13 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestMappings()
{
PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true);
PoolMapper poolMapper = new(DummyProcessHandle, true);
MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
const ulong CpuSize = 0x1000;
const ulong CpuSize = 0x1000;
memoryPoolDsp.SetCpuAddress(CpuAddress, CpuSize);
memoryPoolCpu.SetCpuAddress(CpuAddress, CpuSize);
@@ -72,10 +72,10 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
{
const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
const ulong CpuSize = 0x1000;
const ulong CpuSize = 0x1000;
const int MemoryPoolStateArraySize = 0x10;
const CpuAddress CpuAddressRegionEnding = CpuAddress * MemoryPoolStateArraySize;
const int MemoryPoolStateArraySize = 0x10;
const CpuAddress CpuAddressRegionEnding = CpuAddress * MemoryPoolStateArraySize;
MemoryPoolState[] memoryPoolStateArray = new MemoryPoolState[MemoryPoolStateArraySize];
@@ -85,13 +85,12 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
memoryPoolStateArray[i].SetCpuAddress(CpuAddress + (ulong)i * CpuSize, CpuSize);
}
ErrorInfo errorInfo;
AddressInfo addressInfo = AddressInfo.Create();
PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true);
PoolMapper poolMapper = new(DummyProcessHandle, true);
Assert.IsTrue(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, 0, 0));
Assert.IsTrue(poolMapper.TryAttachBuffer(out ErrorInfo errorInfo, ref addressInfo, 0, 0));
Assert.AreEqual(ResultCode.InvalidAddressInfo, errorInfo.ErrorCode);
Assert.AreEqual(0, errorInfo.ExtraErrorInfo);
@@ -105,7 +104,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
poolMapper = new PoolMapper(DummyProcessHandle, false);
Assert.IsFalse(poolMapper.TryAttachBuffer(out errorInfo, ref addressInfo, 0, 0));
Assert.IsFalse(poolMapper.TryAttachBuffer(out _, ref addressInfo, 0, 0));
addressInfo.ForceMappedDspAddress = 0;

View File

@@ -31,7 +31,7 @@ namespace Ryujinx.Tests.Cpu
new() { Value = 0xffff8fffffff8fff, Valid = true, ImmN = 0, ImmS = 0x1c, ImmR = 17 },
new() { Value = 0x000000000ffff800, Valid = true, ImmN = 1, ImmS = 0x10, ImmR = 53 },
};
[Test]
public void BitImmTests([ValueSource(nameof(TestCases))] TestCase test)
{
@@ -43,4 +43,4 @@ namespace Ryujinx.Tests.Cpu
Assert.That(immR, Is.EqualTo(test.ImmR));
}
}
}
}

View File

@@ -14,13 +14,15 @@ namespace Ryujinx.Tests.Cpu
public class CpuTest
{
protected static readonly ulong Size = MemoryBlock.GetPageSize();
#pragma warning disable CA2211 // Non-constant fields should not be visible
protected static ulong CodeBaseAddress = Size;
protected static ulong DataBaseAddress = CodeBaseAddress + Size;
#pragma warning restore CA2211
private static bool Ignore_FpcrFz = false;
private static bool Ignore_FpcrDn = false;
private static readonly bool _ignoreFpcrFz = false;
private static readonly bool _ignoreFpcrDn = false;
private static bool IgnoreAllExcept_FpsrQc = false;
private static readonly bool _ignoreAllExceptFpsrQc = false;
private ulong _currAddress;
@@ -84,8 +86,8 @@ namespace Ryujinx.Tests.Cpu
_context.Dispose();
_ram.Dispose();
_memory = null;
_context = null;
_memory = null;
_context = null;
_cpuContext = null;
_unicornEmu = null;
@@ -109,38 +111,38 @@ namespace Ryujinx.Tests.Cpu
protected ExecutionContext GetContext() => _context;
protected void SetContext(ulong x0 = 0,
ulong x1 = 0,
ulong x2 = 0,
ulong x3 = 0,
ulong x31 = 0,
V128 v0 = default,
V128 v1 = default,
V128 v2 = default,
V128 v3 = default,
V128 v4 = default,
V128 v5 = default,
V128 v30 = default,
V128 v31 = default,
bool overflow = false,
bool carry = false,
bool zero = false,
bool negative = false,
int fpcr = 0,
int fpsr = 0)
protected void SetContext(ulong x0 = 0,
ulong x1 = 0,
ulong x2 = 0,
ulong x3 = 0,
ulong x31 = 0,
V128 v0 = default,
V128 v1 = default,
V128 v2 = default,
V128 v3 = default,
V128 v4 = default,
V128 v5 = default,
V128 v30 = default,
V128 v31 = default,
bool overflow = false,
bool carry = false,
bool zero = false,
bool negative = false,
int fpcr = 0,
int fpsr = 0)
{
_context.SetX(0, x0);
_context.SetX(1, x1);
_context.SetX(2, x2);
_context.SetX(3, x3);
_context.SetX(0, x0);
_context.SetX(1, x1);
_context.SetX(2, x2);
_context.SetX(3, x3);
_context.SetX(31, x31);
_context.SetV(0, v0);
_context.SetV(1, v1);
_context.SetV(2, v2);
_context.SetV(3, v3);
_context.SetV(4, v4);
_context.SetV(5, v5);
_context.SetV(0, v0);
_context.SetV(1, v1);
_context.SetV(2, v2);
_context.SetV(3, v3);
_context.SetV(4, v4);
_context.SetV(5, v5);
_context.SetV(30, v30);
_context.SetV(31, v31);
@@ -156,20 +158,20 @@ namespace Ryujinx.Tests.Cpu
_unicornEmu.X[1] = x1;
_unicornEmu.X[2] = x2;
_unicornEmu.X[3] = x3;
_unicornEmu.SP = x31;
_unicornEmu.SP = x31;
_unicornEmu.Q[0] = V128ToSimdValue(v0);
_unicornEmu.Q[1] = V128ToSimdValue(v1);
_unicornEmu.Q[2] = V128ToSimdValue(v2);
_unicornEmu.Q[3] = V128ToSimdValue(v3);
_unicornEmu.Q[4] = V128ToSimdValue(v4);
_unicornEmu.Q[5] = V128ToSimdValue(v5);
_unicornEmu.Q[0] = V128ToSimdValue(v0);
_unicornEmu.Q[1] = V128ToSimdValue(v1);
_unicornEmu.Q[2] = V128ToSimdValue(v2);
_unicornEmu.Q[3] = V128ToSimdValue(v3);
_unicornEmu.Q[4] = V128ToSimdValue(v4);
_unicornEmu.Q[5] = V128ToSimdValue(v5);
_unicornEmu.Q[30] = V128ToSimdValue(v30);
_unicornEmu.Q[31] = V128ToSimdValue(v31);
_unicornEmu.OverflowFlag = overflow;
_unicornEmu.CarryFlag = carry;
_unicornEmu.ZeroFlag = zero;
_unicornEmu.CarryFlag = carry;
_unicornEmu.ZeroFlag = zero;
_unicornEmu.NegativeFlag = negative;
_unicornEmu.Fpcr = fpcr;
@@ -186,34 +188,34 @@ namespace Ryujinx.Tests.Cpu
}
}
protected ExecutionContext SingleOpcode(uint opcode,
ulong x0 = 0,
ulong x1 = 0,
ulong x2 = 0,
ulong x3 = 0,
ulong x31 = 0,
V128 v0 = default,
V128 v1 = default,
V128 v2 = default,
V128 v3 = default,
V128 v4 = default,
V128 v5 = default,
V128 v30 = default,
V128 v31 = default,
bool overflow = false,
bool carry = false,
bool zero = false,
bool negative = false,
int fpcr = 0,
int fpsr = 0,
bool runUnicorn = true)
protected ExecutionContext SingleOpcode(uint opcode,
ulong x0 = 0,
ulong x1 = 0,
ulong x2 = 0,
ulong x3 = 0,
ulong x31 = 0,
V128 v0 = default,
V128 v1 = default,
V128 v2 = default,
V128 v3 = default,
V128 v4 = default,
V128 v5 = default,
V128 v30 = default,
V128 v31 = default,
bool overflow = false,
bool carry = false,
bool zero = false,
bool negative = false,
int fpcr = 0,
int fpsr = 0,
bool runUnicorn = true)
{
if (Ignore_FpcrFz)
if (_ignoreFpcrFz)
{
fpcr &= ~(1 << (int)Fpcr.Fz);
}
if (Ignore_FpcrDn)
if (_ignoreFpcrDn)
{
fpcr &= ~(1 << (int)Fpcr.Dn);
}
@@ -254,8 +256,8 @@ namespace Ryujinx.Tests.Cpu
/// <summary>Round towards Minus Infinity mode.</summary>
Rm,
/// <summary>Round towards Zero mode.</summary>
Rz
};
Rz,
}
/// <summary>Floating-point Control Register.</summary>
protected enum Fpcr
@@ -263,15 +265,16 @@ namespace Ryujinx.Tests.Cpu
/// <summary>Rounding Mode control field.</summary>
RMode = 22,
/// <summary>Flush-to-zero mode control bit.</summary>
Fz = 24,
Fz = 24,
/// <summary>Default NaN mode control bit.</summary>
Dn = 25,
Dn = 25,
/// <summary>Alternative half-precision control bit.</summary>
Ahp = 26
Ahp = 26,
}
/// <summary>Floating-point Status Register.</summary>
[Flags] protected enum Fpsr
[Flags]
protected enum Fpsr
{
None = 0,
@@ -289,10 +292,11 @@ namespace Ryujinx.Tests.Cpu
Idc = 1 << 7,
/// <summary>Cumulative saturation bit.</summary>
Qc = 1 << 27
Qc = 1 << 27,
}
[Flags] protected enum FpSkips
[Flags]
protected enum FpSkips
{
None = 0,
@@ -300,7 +304,7 @@ namespace Ryujinx.Tests.Cpu
IfNaND = 2,
IfUnderflow = 4,
IfOverflow = 8
IfOverflow = 8,
}
protected enum FpTolerances
@@ -308,15 +312,15 @@ namespace Ryujinx.Tests.Cpu
None,
UpToOneUlpsS,
UpToOneUlpsD
UpToOneUlpsD,
}
protected void CompareAgainstUnicorn(
Fpsr fpsrMask = Fpsr.None,
FpSkips fpSkips = FpSkips.None,
Fpsr fpsrMask = Fpsr.None,
FpSkips fpSkips = FpSkips.None,
FpTolerances fpTolerances = FpTolerances.None)
{
if (IgnoreAllExcept_FpsrQc)
if (_ignoreAllExceptFpsrQc)
{
fpsrMask &= Fpsr.Qc;
}
@@ -326,6 +330,7 @@ namespace Ryujinx.Tests.Cpu
ManageFpSkips(fpSkips);
}
#pragma warning disable IDE0055 // Disable formatting
Assert.That(_context.GetX(0), Is.EqualTo(_unicornEmu.X[0]), "X0");
Assert.That(_context.GetX(1), Is.EqualTo(_unicornEmu.X[1]), "X1");
Assert.That(_context.GetX(2), Is.EqualTo(_unicornEmu.X[2]), "X2");
@@ -358,6 +363,7 @@ namespace Ryujinx.Tests.Cpu
Assert.That(_context.GetX(29), Is.EqualTo(_unicornEmu.X[29]));
Assert.That(_context.GetX(30), Is.EqualTo(_unicornEmu.X[30]));
Assert.That(_context.GetX(31), Is.EqualTo(_unicornEmu.SP), "X31");
#pragma warning restore IDE0055
if (fpTolerances == FpTolerances.None)
{
@@ -367,6 +373,8 @@ namespace Ryujinx.Tests.Cpu
{
ManageFpTolerances(fpTolerances);
}
#pragma warning disable IDE0055 // Disable formatting
Assert.That(V128ToSimdValue(_context.GetV(1)), Is.EqualTo(_unicornEmu.Q[1]), "V1");
Assert.That(V128ToSimdValue(_context.GetV(2)), Is.EqualTo(_unicornEmu.Q[2]), "V2");
Assert.That(V128ToSimdValue(_context.GetV(3)), Is.EqualTo(_unicornEmu.Q[3]), "V3");
@@ -409,6 +417,7 @@ namespace Ryujinx.Tests.Cpu
Assert.That((int)_context.Fpcr, Is.EqualTo(_unicornEmu.Fpcr), "Fpcr");
Assert.That((int)_context.Fpsr & (int)fpsrMask, Is.EqualTo(_unicornEmu.Fpsr & (int)fpsrMask), "Fpsr");
#pragma warning restore IDE0055
if (_usingMemory)
{
@@ -455,7 +464,7 @@ namespace Ryujinx.Tests.Cpu
private void ManageFpTolerances(FpTolerances fpTolerances)
{
bool IsNormalOrSubnormalS(float f) => float.IsNormal(f) || float.IsSubnormal(f);
bool IsNormalOrSubnormalS(float f) => float.IsNormal(f) || float.IsSubnormal(f);
bool IsNormalOrSubnormalD(double d) => double.IsNormal(d) || double.IsSubnormal(d);
if (!Is.EqualTo(_unicornEmu.Q[0]).ApplyTo(V128ToSimdValue(_context.GetV(0))).IsSuccess)
@@ -467,13 +476,13 @@ namespace Ryujinx.Tests.Cpu
{
Assert.Multiple(() =>
{
Assert.That (_context.GetV(0).Extract<float>(0),
Assert.That(_context.GetV(0).Extract<float>(0),
Is.EqualTo(_unicornEmu.Q[0].GetFloat(0)).Within(1).Ulps, "V0[0]");
Assert.That (_context.GetV(0).Extract<float>(1),
Assert.That(_context.GetV(0).Extract<float>(1),
Is.EqualTo(_unicornEmu.Q[0].GetFloat(1)).Within(1).Ulps, "V0[1]");
Assert.That (_context.GetV(0).Extract<float>(2),
Assert.That(_context.GetV(0).Extract<float>(2),
Is.EqualTo(_unicornEmu.Q[0].GetFloat(2)).Within(1).Ulps, "V0[2]");
Assert.That (_context.GetV(0).Extract<float>(3),
Assert.That(_context.GetV(0).Extract<float>(3),
Is.EqualTo(_unicornEmu.Q[0].GetFloat(3)).Within(1).Ulps, "V0[3]");
});
@@ -492,9 +501,9 @@ namespace Ryujinx.Tests.Cpu
{
Assert.Multiple(() =>
{
Assert.That (_context.GetV(0).Extract<double>(0),
Assert.That(_context.GetV(0).Extract<double>(0),
Is.EqualTo(_unicornEmu.Q[0].GetDouble(0)).Within(1).Ulps, "V0[0]");
Assert.That (_context.GetV(0).Extract<double>(1),
Assert.That(_context.GetV(0).Extract<double>(1),
Is.EqualTo(_unicornEmu.Q[0].GetDouble(1)).Within(1).Ulps, "V0[1]");
});
@@ -513,13 +522,13 @@ namespace Ryujinx.Tests.Cpu
return new SimdValue(value.Extract<ulong>(0), value.Extract<ulong>(1));
}
protected static V128 MakeVectorScalar(float value) => new V128(value);
protected static V128 MakeVectorScalar(double value) => new V128(value);
protected static V128 MakeVectorScalar(float value) => new(value);
protected static V128 MakeVectorScalar(double value) => new(value);
protected static V128 MakeVectorE0(ulong e0) => new V128(e0, 0);
protected static V128 MakeVectorE1(ulong e1) => new V128(0, e1);
protected static V128 MakeVectorE0(ulong e0) => new(e0, 0);
protected static V128 MakeVectorE1(ulong e1) => new(0, e1);
protected static V128 MakeVectorE0E1(ulong e0, ulong e1) => new V128(e0, e1);
protected static V128 MakeVectorE0E1(ulong e0, ulong e1) => new(e0, e1);
protected static ulong GetVectorE0(V128 vector) => vector.Extract<ulong>(0);
protected static ulong GetVectorE1(V128 vector) => vector.Extract<ulong>(1);
@@ -528,8 +537,9 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUShort();
while (( rnd & 0x7C00u) == 0u ||
do
rnd = TestContext.CurrentContext.Random.NextUShort();
while ((rnd & 0x7C00u) == 0u ||
(~rnd & 0x7C00u) == 0u);
return (ushort)rnd;
@@ -539,7 +549,8 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUShort();
do
rnd = TestContext.CurrentContext.Random.NextUShort();
while ((rnd & 0x03FFu) == 0u);
return (ushort)(rnd & 0x83FFu);
@@ -549,8 +560,9 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUInt();
while (( rnd & 0x7F800000u) == 0u ||
do
rnd = TestContext.CurrentContext.Random.NextUInt();
while ((rnd & 0x7F800000u) == 0u ||
(~rnd & 0x7F800000u) == 0u);
return rnd;
@@ -560,7 +572,8 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUInt();
do
rnd = TestContext.CurrentContext.Random.NextUInt();
while ((rnd & 0x007FFFFFu) == 0u);
return rnd & 0x807FFFFFu;
@@ -570,8 +583,9 @@ namespace Ryujinx.Tests.Cpu
{
ulong rnd;
do rnd = TestContext.CurrentContext.Random.NextULong();
while (( rnd & 0x7FF0000000000000ul) == 0ul ||
do
rnd = TestContext.CurrentContext.Random.NextULong();
while ((rnd & 0x7FF0000000000000ul) == 0ul ||
(~rnd & 0x7FF0000000000000ul) == 0ul);
return rnd;
@@ -581,10 +595,11 @@ namespace Ryujinx.Tests.Cpu
{
ulong rnd;
do rnd = TestContext.CurrentContext.Random.NextULong();
do
rnd = TestContext.CurrentContext.Random.NextULong();
while ((rnd & 0x000FFFFFFFFFFFFFul) == 0ul);
return rnd & 0x800FFFFFFFFFFFFFul;
}
}
}
}

View File

@@ -14,8 +14,10 @@ namespace Ryujinx.Tests.Cpu
public class CpuTest32
{
protected static readonly uint Size = (uint)MemoryBlock.GetPageSize();
#pragma warning disable CA2211 // Non-constant fields should not be visible
protected static uint CodeBaseAddress = Size;
protected static uint DataBaseAddress = CodeBaseAddress + Size;
#pragma warning restore CA2211
private uint _currAddress;
@@ -79,8 +81,8 @@ namespace Ryujinx.Tests.Cpu
_context.Dispose();
_ram.Dispose();
_memory = null;
_context = null;
_memory = null;
_context = null;
_cpuContext = null;
_unicornEmu = null;
@@ -288,16 +290,17 @@ namespace Ryujinx.Tests.Cpu
SetWorkingMemory(0, testMem);
RunPrecomputedTestCase(new PrecomputedThumbTestCase(){
RunPrecomputedTestCase(new PrecomputedThumbTestCase
{
Instructions = test.Instructions,
StartRegs = test.StartRegs,
FinalRegs = test.FinalRegs,
});
foreach (var delta in test.MemoryDelta)
foreach (var (address, value) in test.MemoryDelta)
{
testMem[delta.Address - DataBaseAddress + 0] = (byte)(delta.Value >> 0);
testMem[delta.Address - DataBaseAddress + 1] = (byte)(delta.Value >> 8);
testMem[address - DataBaseAddress + 0] = (byte)(value >> 0);
testMem[address - DataBaseAddress + 1] = (byte)(value >> 8);
}
byte[] mem = _memory.GetSpan(DataBaseAddress, (int)Size).ToArray();
@@ -324,8 +327,8 @@ namespace Ryujinx.Tests.Cpu
/// <summary>Round towards Minus Infinity mode.</summary>
Rm,
/// <summary>Round towards Zero mode.</summary>
Rz
};
Rz,
}
/// <summary>Floating-point Control Register.</summary>
protected enum Fpcr
@@ -337,7 +340,7 @@ namespace Ryujinx.Tests.Cpu
/// <summary>Default NaN mode control bit.</summary>
Dn = 25,
/// <summary>Alternative half-precision control bit.</summary>
Ahp = 26
Ahp = 26,
}
/// <summary>Floating-point Status Register.</summary>
@@ -363,7 +366,7 @@ namespace Ryujinx.Tests.Cpu
Qc = 1 << 27,
/// <summary>NZCV flags.</summary>
Nzcv = (1 << 31) | (1 << 30) | (1 << 29) | (1 << 28)
Nzcv = (1 << 31) | (1 << 30) | (1 << 29) | (1 << 28),
}
[Flags]
@@ -375,7 +378,7 @@ namespace Ryujinx.Tests.Cpu
IfNaND = 2,
IfUnderflow = 4,
IfOverflow = 8
IfOverflow = 8,
}
protected enum FpTolerances
@@ -383,7 +386,7 @@ namespace Ryujinx.Tests.Cpu
None,
UpToOneUlpsS,
UpToOneUlpsD
UpToOneUlpsD,
}
protected void CompareAgainstUnicorn(
@@ -554,13 +557,13 @@ namespace Ryujinx.Tests.Cpu
return new SimdValue(value.Extract<ulong>(0), value.Extract<ulong>(1));
}
protected static V128 MakeVectorScalar(float value) => new V128(value);
protected static V128 MakeVectorScalar(double value) => new V128(value);
protected static V128 MakeVectorScalar(float value) => new(value);
protected static V128 MakeVectorScalar(double value) => new(value);
protected static V128 MakeVectorE0(ulong e0) => new V128(e0, 0);
protected static V128 MakeVectorE1(ulong e1) => new V128(0, e1);
protected static V128 MakeVectorE0(ulong e0) => new(e0, 0);
protected static V128 MakeVectorE1(ulong e1) => new(0, e1);
protected static V128 MakeVectorE0E1(ulong e0, ulong e1) => new V128(e0, e1);
protected static V128 MakeVectorE0E1(ulong e0, ulong e1) => new(e0, e1);
protected static V128 MakeVectorE0E1E2E3(uint e0, uint e1, uint e2, uint e3)
{
@@ -574,7 +577,8 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUShort();
do
rnd = TestContext.CurrentContext.Random.NextUShort();
while ((rnd & 0x7C00u) == 0u ||
(~rnd & 0x7C00u) == 0u);
@@ -585,7 +589,8 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUShort();
do
rnd = TestContext.CurrentContext.Random.NextUShort();
while ((rnd & 0x03FFu) == 0u);
return (ushort)(rnd & 0x83FFu);
@@ -595,7 +600,8 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUInt();
do
rnd = TestContext.CurrentContext.Random.NextUInt();
while ((rnd & 0x7F800000u) == 0u ||
(~rnd & 0x7F800000u) == 0u);
@@ -606,7 +612,8 @@ namespace Ryujinx.Tests.Cpu
{
uint rnd;
do rnd = TestContext.CurrentContext.Random.NextUInt();
do
rnd = TestContext.CurrentContext.Random.NextUInt();
while ((rnd & 0x007FFFFFu) == 0u);
return rnd & 0x807FFFFFu;
@@ -616,7 +623,8 @@ namespace Ryujinx.Tests.Cpu
{
ulong rnd;
do rnd = TestContext.CurrentContext.Random.NextULong();
do
rnd = TestContext.CurrentContext.Random.NextULong();
while ((rnd & 0x7FF0000000000000ul) == 0ul ||
(~rnd & 0x7FF0000000000000ul) == 0ul);
@@ -627,10 +635,11 @@ namespace Ryujinx.Tests.Cpu
{
ulong rnd;
do rnd = TestContext.CurrentContext.Random.NextULong();
do
rnd = TestContext.CurrentContext.Random.NextULong();
while ((rnd & 0x000FFFFFFFFFFFFFul) == 0ul);
return rnd & 0x800FFFFFFFFFFFFFul;
}
}
}
}

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.Tests.Cpu
{
#if Alu
#region "Helper methods"
#region "Helper methods"
private static uint GenLeadingSignsMinus32(int cnt) // 0 <= cnt <= 31
{
return ~GenLeadingZeros32(cnt + 1);
@@ -33,29 +33,43 @@ namespace Ryujinx.Tests.Cpu
private static uint GenLeadingZeros32(int cnt) // 0 <= cnt <= 32
{
if (cnt == 32) return 0u;
if (cnt == 31) return 1u;
if (cnt == 32)
{
return 0u;
}
uint rnd = TestContext.CurrentContext.Random.NextUInt();
int mask = int.MinValue;
if (cnt == 31)
{
return 1u;
}
uint rnd = TestContext.CurrentContext.Random.NextUInt();
int mask = int.MinValue;
return (rnd >> (cnt + 1)) | ((uint)mask >> cnt);
}
private static ulong GenLeadingZeros64(int cnt) // 0 <= cnt <= 64
{
if (cnt == 64) return 0ul;
if (cnt == 63) return 1ul;
if (cnt == 64)
{
return 0ul;
}
ulong rnd = TestContext.CurrentContext.Random.NextULong();
long mask = long.MinValue;
if (cnt == 63)
{
return 1ul;
}
ulong rnd = TestContext.CurrentContext.Random.NextULong();
long mask = long.MinValue;
return (rnd >> (cnt + 1)) | ((ulong)mask >> cnt);
}
#endregion
#endregion
#region "ValueSource (Types)"
private static IEnumerable<ulong> _GenLeadingSignsX_()
#region "ValueSource (Types)"
private static IEnumerable<ulong> GenLeadingSignsX()
{
for (int cnt = 0; cnt <= 63; cnt++)
{
@@ -64,7 +78,7 @@ namespace Ryujinx.Tests.Cpu
}
}
private static IEnumerable<uint> _GenLeadingSignsW_()
private static IEnumerable<uint> GenLeadingSignsW()
{
for (int cnt = 0; cnt <= 31; cnt++)
{
@@ -73,7 +87,7 @@ namespace Ryujinx.Tests.Cpu
}
}
private static IEnumerable<ulong> _GenLeadingZerosX_()
private static IEnumerable<ulong> GenLeadingZerosX()
{
for (int cnt = 0; cnt <= 64; cnt++)
{
@@ -81,19 +95,19 @@ namespace Ryujinx.Tests.Cpu
}
}
private static IEnumerable<uint> _GenLeadingZerosW_()
private static IEnumerable<uint> GenLeadingZerosW()
{
for (int cnt = 0; cnt <= 32; cnt++)
{
yield return GenLeadingZeros32(cnt);
}
}
#endregion
#endregion
[Test, Pairwise, Description("CLS <Xd>, <Xn>")]
public void Cls_64bit([Values(0u, 31u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_GenLeadingSignsX_))] ulong xn)
[ValueSource(nameof(GenLeadingSignsX))] ulong xn)
{
uint opcode = 0xDAC01400; // CLS X0, X0
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -108,7 +122,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("CLS <Wd>, <Wn>")]
public void Cls_32bit([Values(0u, 31u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_GenLeadingSignsW_))] uint wn)
[ValueSource(nameof(GenLeadingSignsW))] uint wn)
{
uint opcode = 0x5AC01400; // CLS W0, W0
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -123,7 +137,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("CLZ <Xd>, <Xn>")]
public void Clz_64bit([Values(0u, 31u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_GenLeadingZerosX_))] ulong xn)
[ValueSource(nameof(GenLeadingZerosX))] ulong xn)
{
uint opcode = 0xDAC01000; // CLZ X0, X0
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -138,7 +152,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("CLZ <Wd>, <Wn>")]
public void Clz_32bit([Values(0u, 31u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_GenLeadingZerosW_))] uint wn)
[ValueSource(nameof(GenLeadingZerosW))] uint wn)
{
uint opcode = 0x5AC01000; // CLZ W0, W0
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -263,4 +277,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -9,8 +9,8 @@ namespace Ryujinx.Tests.Cpu
{
#if Alu32
#region "ValueSource (Opcodes)"
private static uint[] _SU_H_AddSub_8_()
#region "ValueSource (Opcodes)"
private static uint[] SuHAddSub8()
{
return new[]
{
@@ -21,22 +21,22 @@ namespace Ryujinx.Tests.Cpu
0xe6500f90u, // UADD8 R0, R0, R0
0xe6500ff0u, // USUB8 R0, R0, R0
0xe6700f90u, // UHADD8 R0, R0, R0
0xe6700ff0u // UHSUB8 R0, R0, R0
0xe6700ff0u, // UHSUB8 R0, R0, R0
};
}
private static uint[] _Ssat_Usat_()
private static uint[] SsatUsat()
{
return new[]
{
0xe6a00010u, // SSAT R0, #1, R0, LSL #0
0xe6a00050u, // SSAT R0, #1, R0, ASR #32
0xe6e00010u, // USAT R0, #0, R0, LSL #0
0xe6e00050u // USAT R0, #0, R0, ASR #32
0xe6e00050u, // USAT R0, #0, R0, ASR #32
};
}
private static uint[] _Ssat16_Usat16_()
private static uint[] Ssat16Usat16()
{
return new[]
{
@@ -45,17 +45,17 @@ namespace Ryujinx.Tests.Cpu
};
}
private static uint[] _Lsr_Lsl_Asr_Ror_()
private static uint[] LsrLslAsrRor()
{
return new[]
{
0xe1b00030u, // LSRS R0, R0, R0
0xe1b00010u, // LSLS R0, R0, R0
0xe1b00050u, // ASRS R0, R0, R0
0xe1b00070u // RORS R0, R0, R0
0xe1b00070u, // RORS R0, R0, R0
};
}
#endregion
#endregion
private const int RndCnt = 2;
@@ -76,7 +76,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise]
public void Lsr_Lsl_Asr_Ror([ValueSource(nameof(_Lsr_Lsl_Asr_Ror_))] uint opcode,
public void Lsr_Lsl_Asr_Ror([ValueSource(nameof(LsrLslAsrRor))] uint opcode,
[Values(0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu)] uint shiftValue,
[Range(0, 31)] int shiftAmount)
@@ -130,7 +130,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise]
public void Ssat_Usat([ValueSource(nameof(_Ssat_Usat_))] uint opcode,
public void Ssat_Usat([ValueSource(nameof(SsatUsat))] uint opcode,
[Values(0u, 0xdu)] uint rd,
[Values(1u, 0xdu)] uint rn,
[Values(0u, 7u, 8u, 0xfu, 0x10u, 0x1fu)] uint sat,
@@ -148,7 +148,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise]
public void Ssat16_Usat16([ValueSource(nameof(_Ssat16_Usat16_))] uint opcode,
public void Ssat16_Usat16([ValueSource(nameof(Ssat16Usat16))] uint opcode,
[Values(0u, 0xdu)] uint rd,
[Values(1u, 0xdu)] uint rn,
[Values(0u, 7u, 8u, 0xfu)] uint sat,
@@ -165,7 +165,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise]
public void SU_H_AddSub_8([ValueSource(nameof(_SU_H_AddSub_8_))] uint opcode,
public void SU_H_AddSub_8([ValueSource(nameof(SuHAddSub8))] uint opcode,
[Values(0u, 0xdu)] uint rd,
[Values(1u)] uint rm,
[Values(2u)] uint rn,
@@ -191,9 +191,9 @@ namespace Ryujinx.Tests.Cpu
[Random(RndCnt)] uint w2)
{
uint opUadd8 = 0xE6500F90; // UADD8 R0, R0, R0
uint opSel = 0xE6800FB0; // SEL R0, R0, R0
uint opSel = 0xE6800FB0; // SEL R0, R0, R0
opUadd8 |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
opUadd8 |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
opSel |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
SetContext(r0: w0, r1: w1, r2: w2);
@@ -206,4 +206,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -26,7 +26,7 @@ namespace Ryujinx.Tests.Cpu
}
}
#region "ValueSource (CRC32)"
#region "ValueSource (CRC32)"
private static CrcTest[] _CRC32_Test_Values_()
{
// Created with http://www.sunshine2k.de/coding/javascript/crc/crc_js.html, with:
@@ -48,10 +48,10 @@ namespace Ryujinx.Tests.Cpu
new CrcTest(0xffffffffu, 0x7f_ff_ff_ff_ff_ff_ff_ffu, false, 0x00ffffff, 0x0000ffff, 0x00000000, 0x3303a3c3),
new CrcTest(0xffffffffu, 0x80_00_00_00_00_00_00_00u, false, 0x2dfd1072, 0xbe26ed00, 0xdebb20e3, 0x7765a3b6),
new CrcTest(0xffffffffu, 0xff_ff_ff_ff_ff_ff_ff_ffu, false, 0x00ffffff, 0x0000ffff, 0x00000000, 0xdebb20e3),
new CrcTest(0xffffffffu, 0xa0_02_f1_ca_52_78_8c_1cu, false, 0x39fc4c3d, 0xbc5f7f56, 0x4ed8e906, 0x12cb419c)
new CrcTest(0xffffffffu, 0xa0_02_f1_ca_52_78_8c_1cu, false, 0x39fc4c3d, 0xbc5f7f56, 0x4ed8e906, 0x12cb419c),
};
}
#endregion
#endregion
[Test, Combinatorial]
public void Crc32_b_h_w_x([Values(0u)] uint rd,
@@ -304,4 +304,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -27,7 +27,7 @@ namespace Ryujinx.Tests.Cpu
}
}
#region "ValueSource (CRC32/CRC32C)"
#region "ValueSource (CRC32/CRC32C)"
private static CrcTest32[] _CRC32_Test_Values_()
{
// Created with http://www.sunshine2k.de/coding/javascript/crc/crc_js.html, with:
@@ -60,10 +60,10 @@ namespace Ryujinx.Tests.Cpu
new CrcTest32(0xffffffffu, 0x7f_ff_ff_ffu, true, 0x00ffffff, 0x0000ffff, 0x82f63b78),
new CrcTest32(0xffffffffu, 0x80_00_00_00u, true, 0xad82acae, 0x0e9e882d, 0x356e8f40),
new CrcTest32(0xffffffffu, 0xff_ff_ff_ffu, true, 0x00ffffff, 0x0000ffff, 0x00000000),
new CrcTest32(0xffffffffu, 0x9d_cb_12_f0u, true, 0x5eecc3db, 0xbb6111cb, 0xcfb54fc9)
new CrcTest32(0xffffffffu, 0x9d_cb_12_f0u, true, 0x5eecc3db, 0xbb6111cb, 0xcfb54fc9),
};
}
#endregion
#endregion
[Test, Combinatorial]
public void Crc32_Crc32c_b_h_w([Values(0u)] uint rd,

View File

@@ -430,4 +430,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -9,8 +9,8 @@ namespace Ryujinx.Tests.Cpu
{
#if AluRs32
#region "ValueSource (Opcodes)"
private static uint[] _opcodes()
#region "ValueSource (Opcodes)"
private static uint[] Opcodes()
{
return new[]
{
@@ -30,12 +30,12 @@ namespace Ryujinx.Tests.Cpu
0xe2500000u, // SUBS R0, R0, #0
};
}
#endregion
#endregion
private const int RndCnt = 2;
[Test, Pairwise]
public void TestCpuTestAluImm32([ValueSource(nameof(_opcodes))] uint opcode,
public void TestCpuTestAluImm32([ValueSource(nameof(Opcodes))] uint opcode,
[Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Random(RndCnt)] uint imm,
@@ -52,4 +52,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -892,4 +892,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu
{
#if AluRs32
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Add_Adds_Rsb_Rsbs_()
{
return new[]
@@ -17,7 +17,7 @@ namespace Ryujinx.Tests.Cpu
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
0xe0700000u, // RSBS R0, R0, R0, LSL #0
};
}
@@ -30,14 +30,14 @@ namespace Ryujinx.Tests.Cpu
0xe0e00000u, // RSC R0, R0, R0
0xe0f00000u, // RSCS R0, R0, R0
0xe0c00000u, // SBC R0, R0, R0
0xe0d00000u // SBCS R0, R0, R0
0xe0d00000u, // SBCS R0, R0, R0
};
}
#endregion
#endregion
[Test, Pairwise]
public void Adc_Adcs_Rsc_Rscs_Sbc_Sbcs([ValueSource("_Adc_Adcs_Rsc_Rscs_Sbc_Sbcs_")] uint opcode,
public void Adc_Adcs_Rsc_Rscs_Sbc_Sbcs([ValueSource(nameof(_Adc_Adcs_Rsc_Rscs_Sbc_Sbcs_))] uint opcode,
[Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
@@ -57,7 +57,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise]
public void Add_Adds_Rsb_Rsbs([ValueSource("_Add_Adds_Rsb_Rsbs_")] uint opcode,
public void Add_Adds_Rsb_Rsbs([ValueSource(nameof(_Add_Adds_Rsb_Rsbs_))] uint opcode,
[Values(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm,
@@ -79,4 +79,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -720,4 +720,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -103,4 +103,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.Tests.Cpu
public sealed class CpuTestBfm : CpuTest
{
#if Bfm
private const int RndCnt = 2;
private const int RndCnt = 2;
[Test, Pairwise, Description("BFM <Xd>, <Xn>, #<immr>, #<imms>")]
public void Bfm_64bit([Values(0u, 31u)] uint rd,
@@ -127,4 +127,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -99,4 +99,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -107,4 +107,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -202,4 +202,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -12,7 +12,7 @@ namespace Ryujinx.Tests.Cpu
{
#if Misc
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static IEnumerable<ulong> _1S_F_()
{
yield return 0x00000000FF7FFFFFul; // -Max Normal (float.MinValue)
@@ -24,19 +24,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -54,15 +54,15 @@ namespace Ryujinx.Tests.Cpu
yield return (grbg << 32) | rnd2;
}
}
#endregion
#endregion
private const int RndCnt = 2;
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
#region "AluImm & Csel"
#region "AluImm & Csel"
[Test, Pairwise]
public void Adds_Csinc_64bit([Values(0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul)] ulong xn,
@@ -73,10 +73,10 @@ namespace Ryujinx.Tests.Cpu
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
{
uint opCmn = 0xB100001F; // ADDS X31, X0, #0, LSL #0 -> CMN X0, #0, LSL #0
uint opCmn = 0xB100001F; // ADDS X31, X0, #0, LSL #0 -> CMN X0, #0, LSL #0
uint opCset = 0x9A9F07E0; // CSINC X0, X31, X31, EQ -> CSET X0, NE
opCmn |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCmn |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCset |= ((cond & 15) << 12);
SetContext(x0: xn);
@@ -98,10 +98,10 @@ namespace Ryujinx.Tests.Cpu
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
{
uint opCmn = 0x3100001F; // ADDS W31, W0, #0, LSL #0 -> CMN W0, #0, LSL #0
uint opCmn = 0x3100001F; // ADDS W31, W0, #0, LSL #0 -> CMN W0, #0, LSL #0
uint opCset = 0x1A9F07E0; // CSINC W0, W31, W31, EQ -> CSET W0, NE
opCmn |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCmn |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCset |= ((cond & 15) << 12);
SetContext(x0: wn);
@@ -123,10 +123,10 @@ namespace Ryujinx.Tests.Cpu
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
{
uint opCmp = 0xF100001F; // SUBS X31, X0, #0, LSL #0 -> CMP X0, #0, LSL #0
uint opCmp = 0xF100001F; // SUBS X31, X0, #0, LSL #0 -> CMP X0, #0, LSL #0
uint opCset = 0x9A9F07E0; // CSINC X0, X31, X31, EQ -> CSET X0, NE
opCmp |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCmp |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCset |= ((cond & 15) << 12);
SetContext(x0: xn);
@@ -148,10 +148,10 @@ namespace Ryujinx.Tests.Cpu
0b1000u, 0b1001u, 0b1010u, 0b1011u, // HI, LS, GE, LT,
0b1100u, 0b1101u)] uint cond) // GT, LE>
{
uint opCmp = 0x7100001F; // SUBS W31, W0, #0, LSL #0 -> CMP W0, #0, LSL #0
uint opCmp = 0x7100001F; // SUBS W31, W0, #0, LSL #0 -> CMP W0, #0, LSL #0
uint opCset = 0x1A9F07E0; // CSINC W0, W31, W31, EQ -> CSET W0, NE
opCmp |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCmp |= ((shift & 3) << 22) | ((imm & 4095) << 10);
opCset |= ((cond & 15) << 12);
SetContext(x0: wn);
@@ -162,10 +162,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
#endregion
#endregion
// Roots.
[Explicit]
[TestCase(0xFFFFFFFDu)] // Roots.
[TestCase(0xFFFFFFFDu)]
[TestCase(0x00000005u)]
public void Misc1(uint a)
{
@@ -196,25 +197,26 @@ namespace Ryujinx.Tests.Cpu
Assert.That(GetContext().GetX(0), Is.Zero);
}
// 18 integer solutions.
[Explicit]
[TestCase(-20f, -5f)] // 18 integer solutions.
[TestCase(-12f, -6f)]
[TestCase(-12f, 3f)]
[TestCase( -8f, -8f)]
[TestCase( -6f, -12f)]
[TestCase( -5f, -20f)]
[TestCase( -4f, 2f)]
[TestCase( -3f, 12f)]
[TestCase( -2f, 4f)]
[TestCase( 2f, -4f)]
[TestCase( 3f, -12f)]
[TestCase( 4f, -2f)]
[TestCase( 5f, 20f)]
[TestCase( 6f, 12f)]
[TestCase( 8f, 8f)]
[TestCase( 12f, -3f)]
[TestCase( 12f, 6f)]
[TestCase( 20f, 5f)]
[TestCase(-20f, -5f)]
[TestCase(-12f, -6f)]
[TestCase(-12f, 3f)]
[TestCase(-8f, -8f)]
[TestCase(-6f, -12f)]
[TestCase(-5f, -20f)]
[TestCase(-4f, 2f)]
[TestCase(-3f, 12f)]
[TestCase(-2f, 4f)]
[TestCase(2f, -4f)]
[TestCase(3f, -12f)]
[TestCase(4f, -2f)]
[TestCase(5f, 20f)]
[TestCase(6f, 12f)]
[TestCase(8f, 8f)]
[TestCase(12f, -3f)]
[TestCase(12f, 6f)]
[TestCase(20f, 5f)]
public void Misc2(float a, float b)
{
// 1 / ((1 / a + 1 / b) ^ 2) = 16
@@ -242,25 +244,26 @@ namespace Ryujinx.Tests.Cpu
Assert.That(GetContext().GetV(0).As<float>(), Is.EqualTo(16f));
}
// 18 integer solutions.
[Explicit]
[TestCase(-20d, -5d)] // 18 integer solutions.
[TestCase(-12d, -6d)]
[TestCase(-12d, 3d)]
[TestCase( -8d, -8d)]
[TestCase( -6d, -12d)]
[TestCase( -5d, -20d)]
[TestCase( -4d, 2d)]
[TestCase( -3d, 12d)]
[TestCase( -2d, 4d)]
[TestCase( 2d, -4d)]
[TestCase( 3d, -12d)]
[TestCase( 4d, -2d)]
[TestCase( 5d, 20d)]
[TestCase( 6d, 12d)]
[TestCase( 8d, 8d)]
[TestCase( 12d, -3d)]
[TestCase( 12d, 6d)]
[TestCase( 20d, 5d)]
[TestCase(-20d, -5d)]
[TestCase(-12d, -6d)]
[TestCase(-12d, 3d)]
[TestCase(-8d, -8d)]
[TestCase(-6d, -12d)]
[TestCase(-5d, -20d)]
[TestCase(-4d, 2d)]
[TestCase(-3d, 12d)]
[TestCase(-2d, 4d)]
[TestCase(2d, -4d)]
[TestCase(3d, -12d)]
[TestCase(4d, -2d)]
[TestCase(5d, 20d)]
[TestCase(6d, 12d)]
[TestCase(8d, 8d)]
[TestCase(12d, -3d)]
[TestCase(12d, 6d)]
[TestCase(20d, 5d)]
public void Misc3(double a, double b)
{
// 1 / ((1 / a + 1 / b) ^ 2) = 16
@@ -291,7 +294,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Ignore("The Tester supports only one return point.")]
public void MiscF([Range(0u, 92u, 1u)] uint a)
{
ulong Fn(uint n)
static ulong Fn(uint n)
{
ulong x = 0, y = 1, z;
@@ -395,9 +398,9 @@ namespace Ryujinx.Tests.Cpu
}
[Explicit]
[TestCase( 0ul)]
[TestCase( 1ul)]
[TestCase( 2ul)]
[TestCase(0ul)]
[TestCase(1ul)]
[TestCase(2ul)]
[TestCase(42ul)]
public void SanityCheck(ulong a)
{
@@ -439,8 +442,8 @@ namespace Ryujinx.Tests.Cpu
v1: MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong()),
v2: MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong()),
overflow: TestContext.CurrentContext.Random.NextBool(),
carry: TestContext.CurrentContext.Random.NextBool(),
zero: TestContext.CurrentContext.Random.NextBool(),
carry: TestContext.CurrentContext.Random.NextBool(),
zero: TestContext.CurrentContext.Random.NextBool(),
negative: TestContext.CurrentContext.Random.NextBool());
Opcode(0xBD400001); // LDR S1, [X0,#0]
@@ -463,8 +466,8 @@ namespace Ryujinx.Tests.Cpu
v0: MakeVectorE0E1(a, TestContext.CurrentContext.Random.NextULong()),
v1: MakeVectorE0E1(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong()),
overflow: TestContext.CurrentContext.Random.NextBool(),
carry: TestContext.CurrentContext.Random.NextBool(),
zero: TestContext.CurrentContext.Random.NextBool(),
carry: TestContext.CurrentContext.Random.NextBool(),
zero: TestContext.CurrentContext.Random.NextBool(),
negative: TestContext.CurrentContext.Random.NextBool());
Opcode(0x1E202008); // FCMP S0, #0.0

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Tests.Cpu
{
#if Misc32
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static IEnumerable<ulong> _1S_F_()
{
yield return 0x00000000FF7FFFFFul; // -Max Normal (float.MinValue)
@@ -23,19 +23,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -53,13 +53,13 @@ namespace Ryujinx.Tests.Cpu
yield return (grbg << 32) | rnd2;
}
}
#endregion
#endregion
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise]
public void Vmsr_Vcmp_Vmrs([ValueSource(nameof(_1S_F_))] ulong a,
@@ -75,10 +75,10 @@ namespace Ryujinx.Tests.Cpu
? TestContext.CurrentContext.Random.NextUInt(0xf) << 28
: TestContext.CurrentContext.Random.NextUInt();
bool v = mode3 ? TestContext.CurrentContext.Random.NextBool() : false;
bool c = mode3 ? TestContext.CurrentContext.Random.NextBool() : false;
bool z = mode3 ? TestContext.CurrentContext.Random.NextBool() : false;
bool n = mode3 ? TestContext.CurrentContext.Random.NextBool() : false;
bool v = mode3 && TestContext.CurrentContext.Random.NextBool();
bool c = mode3 && TestContext.CurrentContext.Random.NextBool();
bool z = mode3 && TestContext.CurrentContext.Random.NextBool();
bool n = mode3 && TestContext.CurrentContext.Random.NextBool();
int fpscr = mode1
? (int)TestContext.CurrentContext.Random.NextUInt()

View File

@@ -8,7 +8,7 @@ namespace Ryujinx.Tests.Cpu
public sealed class CpuTestMov : CpuTest
{
#if Mov
private const int RndCnt = 2;
private const int RndCnt = 2;
[Test, Pairwise, Description("MOVK <Xd>, #<imm>{, LSL #<shift>}")]
public void Movk_64bit([Values(0u, 31u)] uint rd,
@@ -109,4 +109,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -223,4 +223,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu
{
#if Mul32
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Smlabb_Smlabt_Smlatb_Smlatt_()
{
return new[]
@@ -49,10 +49,10 @@ namespace Ryujinx.Tests.Cpu
0xe12000e0u, // SMULWT R0, R0, R0
};
}
#endregion
#endregion
[Test, Pairwise, Description("SMLA<x><y> <Rd>, <Rn>, <Rm>, <Ra>")]
public void Smla___32bit([ValueSource("_Smlabb_Smlabt_Smlatb_Smlatt_")] uint opcode,
public void Smla___32bit([ValueSource(nameof(_Smlabb_Smlabt_Smlatb_Smlatt_))] uint opcode,
[Values(0u, 0xdu)] uint rn,
[Values(1u, 0xdu)] uint rm,
[Values(2u, 0xdu)] uint ra,
@@ -74,7 +74,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("SMLAW<x> <Rd>, <Rn>, <Rm>, <Ra>")]
public void Smlaw__32bit([ValueSource("_Smlawb_Smlawt_")] uint opcode,
public void Smlaw__32bit([ValueSource(nameof(_Smlawb_Smlawt_))] uint opcode,
[Values(0u, 0xdu)] uint rn,
[Values(1u, 0xdu)] uint rm,
[Values(2u, 0xdu)] uint ra,
@@ -96,7 +96,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("SMUL<x><y> <Rd>, <Rn>, <Rm>")]
public void Smul___32bit([ValueSource("_Smulbb_Smulbt_Smultb_Smultt_")] uint opcode,
public void Smul___32bit([ValueSource(nameof(_Smulbb_Smulbt_Smultb_Smultt_))] uint opcode,
[Values(0u, 0xdu)] uint rn,
[Values(1u, 0xdu)] uint rm,
[Values(2u, 0xdu)] uint rd,
@@ -115,7 +115,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("SMULW<x> <Rd>, <Rn>, <Rm>")]
public void Smulw__32bit([ValueSource("_Smulwb_Smulwt_")] uint opcode,
public void Smulw__32bit([ValueSource(nameof(_Smulwb_Smulwt_))] uint opcode,
[Values(0u, 0xdu)] uint rn,
[Values(1u, 0xdu)] uint rm,
[Values(2u, 0xdu)] uint rd,
@@ -134,4 +134,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,14 +11,14 @@ namespace Ryujinx.Tests.Cpu
{
#if Simd32
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Vabs_Vneg_Vpaddl_I_()
{
return new[]
{
0xf3b10300u, // VABS.S8 D0, D0
0xf3b10380u, // VNEG.S8 D0, D0
0xf3b00200u // VPADDL.S8 D0, D0
0xf3b00200u, // VPADDL.S8 D0, D0
};
}
@@ -27,18 +27,20 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0xf3b90700u, // VABS.F32 D0, D0
0xf3b90780u // VNEG.F32 D0, D0
0xf3b90780u, // VNEG.F32 D0, D0
};
}
#endregion
#endregion
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _8B4H2S_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static IEnumerable<ulong> _1S_F_()
@@ -52,19 +54,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -94,19 +96,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x007FFFFF007FFFFFul; // +Max Subnormal
yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFF800000FF800000ul; // -Infinity
yield return 0x7F8000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload)
@@ -135,19 +137,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@@ -173,13 +175,13 @@ namespace Ryujinx.Tests.Cpu
(cnt << 24) | (cnt << 16) | (cnt << 08) | cnt;
}
}
#endregion
#endregion
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise, Description("SHA256SU0.32 <Qd>, <Qm>")]
public void Sha256su0_V([Values(0xF3BA03C0u)] uint opcode,
@@ -193,7 +195,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0x74CED221E2793F07ul)] ulong resultH)
{
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(z0, z1);
V128 v1 = MakeVectorE0E1(a0, a1);
@@ -223,12 +225,14 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rm >>= 1;
rm <<= 1;
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= (size & 0x3) << 18;
@@ -252,12 +256,14 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rm >>= 1;
rm <<= 1;
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(z, ~z);
V128 v1 = MakeVectorE0E1(b, ~b);
@@ -286,7 +292,7 @@ namespace Ryujinx.Tests.Cpu
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(d0, d1);
@@ -303,12 +309,13 @@ namespace Ryujinx.Tests.Cpu
[Values(0u, 1u, 2u, 3u)] uint op,
[Values(0u, 1u, 2u)] uint size) // <S8, S16, S32>
{
rm >>= 1; rm <<= 1;
rm >>= 1;
rm <<= 1;
uint opcode = 0xf3b20200u; // VMOVN.S16 D0, Q0
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= (op & 0x3) << 6;
opcode |= (size & 0x3) << 18;
@@ -322,4 +329,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -1,7 +1,6 @@
// https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf
using ARMeilleure.State;
using NUnit.Framework;
namespace Ryujinx.Tests.Cpu
@@ -13,8 +12,8 @@ namespace Ryujinx.Tests.Cpu
[Values(1u)] uint rn,
[Values(0x7B5B546573745665ul)] ulong valueH,
[Values(0x63746F725D53475Dul)] ulong valueL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Values(0x8DCAB9BC035006BCul)] ulong resultH,
[Values(0x8F57161E00CAFD8Dul)] ulong resultL)
{
@@ -22,7 +21,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
V128 v0 = MakeVectorE0E1(roundKeyL ^ valueL, roundKeyH ^ valueH);
V128 v1 = MakeVectorE0E1(roundKeyL, roundKeyH);
V128 v1 = MakeVectorE0E1(roundKeyL, roundKeyH);
ExecutionContext context = SingleOpcode(opcode, v0: v0, v1: v1);
@@ -45,8 +44,8 @@ namespace Ryujinx.Tests.Cpu
[Values(1u)] uint rn,
[Values(0x7B5B546573745665ul)] ulong valueH,
[Values(0x63746F725D53475Dul)] ulong valueL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Values(0x8F92A04DFBED204Dul)] ulong resultH,
[Values(0x4C39B1402192A84Cul)] ulong resultL)
{
@@ -54,7 +53,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
V128 v0 = MakeVectorE0E1(roundKeyL ^ valueL, roundKeyH ^ valueH);
V128 v1 = MakeVectorE0E1(roundKeyL, roundKeyH);
V128 v1 = MakeVectorE0E1(roundKeyL, roundKeyH);
ExecutionContext context = SingleOpcode(opcode, v0: v0, v1: v1);
@@ -73,7 +72,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Description("AESIMC <Vd>.16B, <Vn>.16B")]
public void Aesimc_V([Values(0u)] uint rd,
public void Aesimc_V([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(0x8DCAB9DC035006BCul)] ulong valueH,
[Values(0x8F57161E00CAFD8Dul)] ulong valueL,
@@ -87,8 +86,8 @@ namespace Ryujinx.Tests.Cpu
ExecutionContext context = SingleOpcode(
opcode,
v0: rn == 0u ? v : default(V128),
v1: rn == 1u ? v : default(V128));
v0: rn == 0u ? v : default,
v1: rn == 1u ? v : default);
Assert.Multiple(() =>
{
@@ -108,7 +107,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Description("AESMC <Vd>.16B, <Vn>.16B")]
public void Aesmc_V([Values(0u)] uint rd,
public void Aesmc_V([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(0x627A6F6644B109C8ul)] ulong valueH,
[Values(0x2B18330A81C3B3E5ul)] ulong valueL,
@@ -122,8 +121,8 @@ namespace Ryujinx.Tests.Cpu
ExecutionContext context = SingleOpcode(
opcode,
v0: rn == 0u ? v : default(V128),
v1: rn == 1u ? v : default(V128));
v0: rn == 0u ? v : default,
v1: rn == 1u ? v : default);
Assert.Multiple(() =>
{

View File

@@ -1,7 +1,6 @@
// https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf
using ARMeilleure.State;
using NUnit.Framework;
namespace Ryujinx.Tests.Cpu
@@ -13,8 +12,8 @@ namespace Ryujinx.Tests.Cpu
[Values(2u)] uint rm,
[Values(0x7B5B546573745665ul)] ulong valueH,
[Values(0x63746F725D53475Dul)] ulong valueL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Values(0x8DCAB9BC035006BCul)] ulong resultH,
[Values(0x8F57161E00CAFD8Dul)] ulong resultL)
{
@@ -47,8 +46,8 @@ namespace Ryujinx.Tests.Cpu
[Values(2u)] uint rm,
[Values(0x7B5B546573745665ul)] ulong valueH,
[Values(0x63746F725D53475Dul)] ulong valueL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Random(2)] ulong roundKeyH,
[Random(2)] ulong roundKeyL,
[Values(0x8F92A04DFBED204Dul)] ulong resultH,
[Values(0x4C39B1402192A84Cul)] ulong resultL)
{
@@ -77,7 +76,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Description("AESIMC.8 <Qd>, <Qm>")]
public void Aesimc_V([Values(0u)] uint rd,
public void Aesimc_V([Values(0u)] uint rd,
[Values(2u, 0u)] uint rm,
[Values(0x8DCAB9DC035006BCul)] ulong valueH,
[Values(0x8F57161E00CAFD8Dul)] ulong valueL,
@@ -92,8 +91,8 @@ namespace Ryujinx.Tests.Cpu
ExecutionContext context = SingleOpcode(
opcode,
v0: rm == 0u ? v : default(V128),
v1: rm == 2u ? v : default(V128),
v0: rm == 0u ? v : default,
v1: rm == 2u ? v : default,
runUnicorn: false);
Assert.Multiple(() =>
@@ -115,7 +114,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Description("AESMC.8 <Qd>, <Qm>")]
public void Aesmc_V([Values(0u)] uint rd,
public void Aesmc_V([Values(0u)] uint rd,
[Values(2u, 0u)] uint rm,
[Values(0x627A6F6644B109C8ul)] ulong valueH,
[Values(0x2B18330A81C3B3E5ul)] ulong valueL,
@@ -130,8 +129,8 @@ namespace Ryujinx.Tests.Cpu
ExecutionContext context = SingleOpcode(
opcode,
v0: rm == 0u ? v : default(V128),
v1: rm == 2u ? v : default(V128),
v0: rm == 0u ? v : default,
v1: rm == 2u ? v : default,
runUnicorn: false);
Assert.Multiple(() =>

View File

@@ -12,17 +12,21 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdCvt
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static uint[] _W_()
{
return new[] { 0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu };
return new[] {
0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu,
};
}
private static ulong[] _X_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static IEnumerable<ulong> _1S_F_WX_()
@@ -62,19 +66,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -145,19 +149,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@@ -188,9 +192,9 @@ namespace Ryujinx.Tests.Cpu
yield return rnd6;
}
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _F_Cvt_AMPZ_SU_Gp_SW_()
{
return new[]
@@ -203,7 +207,7 @@ namespace Ryujinx.Tests.Cpu
0x1E280000u, // FCVTPS W0, S0
0x1E290000u, // FCVTPU W0, S0
0x1E380000u, // FCVTZS W0, S0
0x1E390000u // FCVTZU W0, S0
0x1E390000u, // FCVTZU W0, S0
};
}
@@ -219,7 +223,7 @@ namespace Ryujinx.Tests.Cpu
0x9E280000u, // FCVTPS X0, S0
0x9E290000u, // FCVTPU X0, S0
0x9E380000u, // FCVTZS X0, S0
0x9E390000u // FCVTZU X0, S0
0x9E390000u, // FCVTZU X0, S0
};
}
@@ -235,7 +239,7 @@ namespace Ryujinx.Tests.Cpu
0x1E680000u, // FCVTPS W0, D0
0x1E690000u, // FCVTPU W0, D0
0x1E780000u, // FCVTZS W0, D0
0x1E790000u // FCVTZU W0, D0
0x1E790000u, // FCVTZU W0, D0
};
}
@@ -251,7 +255,7 @@ namespace Ryujinx.Tests.Cpu
0x9E680000u, // FCVTPS X0, D0
0x9E690000u, // FCVTPU X0, D0
0x9E780000u, // FCVTZS X0, D0
0x9E790000u // FCVTZU X0, D0
0x9E790000u, // FCVTZU X0, D0
};
}
@@ -260,7 +264,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x1E188000u, // FCVTZS W0, S0, #32
0x1E198000u // FCVTZU W0, S0, #32
0x1E198000u, // FCVTZU W0, S0, #32
};
}
@@ -269,7 +273,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x9E180000u, // FCVTZS X0, S0, #64
0x9E190000u // FCVTZU X0, S0, #64
0x9E190000u, // FCVTZU X0, S0, #64
};
}
@@ -278,7 +282,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x1E588000u, // FCVTZS W0, D0, #32
0x1E598000u // FCVTZU W0, D0, #32
0x1E598000u, // FCVTZU W0, D0, #32
};
}
@@ -287,7 +291,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x9E580000u, // FCVTZS X0, D0, #64
0x9E590000u // FCVTZU X0, D0, #64
0x9E590000u, // FCVTZU X0, D0, #64
};
}
@@ -296,7 +300,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x1E220000u, // SCVTF S0, W0
0x1E230000u // UCVTF S0, W0
0x1E230000u, // UCVTF S0, W0
};
}
@@ -305,7 +309,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x1E620000u, // SCVTF D0, W0
0x1E630000u // UCVTF D0, W0
0x1E630000u, // UCVTF D0, W0
};
}
@@ -314,7 +318,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x9E220000u, // SCVTF S0, X0
0x9E230000u // UCVTF S0, X0
0x9E230000u, // UCVTF S0, X0
};
}
@@ -323,7 +327,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x9E620000u, // SCVTF D0, X0
0x9E630000u // UCVTF D0, X0
0x9E630000u, // UCVTF D0, X0
};
}
@@ -332,7 +336,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x1E028000u, // SCVTF S0, W0, #32
0x1E038000u // UCVTF S0, W0, #32
0x1E038000u, // UCVTF S0, W0, #32
};
}
@@ -341,7 +345,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x1E428000u, // SCVTF D0, W0, #32
0x1E438000u // UCVTF D0, W0, #32
0x1E438000u, // UCVTF D0, W0, #32
};
}
@@ -350,7 +354,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x9E020000u, // SCVTF S0, X0, #64
0x9E030000u // UCVTF S0, X0, #64
0x9E030000u, // UCVTF S0, X0, #64
};
}
@@ -359,21 +363,22 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x9E420000u, // SCVTF D0, X0, #64
0x9E430000u // UCVTF D0, X0, #64
0x9E430000u, // UCVTF D0, X0, #64
};
}
#endregion
#endregion
private const int RndCnt = 2;
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_AMPZ_SU_Gp_SW([ValueSource(nameof(_F_Cvt_AMPZ_SU_Gp_SW_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1S_F_WX_))] ulong a)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -387,10 +392,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_AMPZ_SU_Gp_SX([ValueSource(nameof(_F_Cvt_AMPZ_SU_Gp_SX_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1S_F_WX_))] ulong a)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -403,10 +409,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_AMPZ_SU_Gp_DW([ValueSource(nameof(_F_Cvt_AMPZ_SU_Gp_DW_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1D_F_WX_))] ulong a)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -420,10 +427,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_AMPZ_SU_Gp_DX([ValueSource(nameof(_F_Cvt_AMPZ_SU_Gp_DX_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1D_F_WX_))] ulong a)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
@@ -436,10 +444,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_Z_SU_Gp_Fixed_SW([ValueSource(nameof(_F_Cvt_Z_SU_Gp_Fixed_SW_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1S_F_WX_))] ulong a,
[Values(1u, 32u)] uint fBits)
{
@@ -457,10 +466,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_Z_SU_Gp_Fixed_SX([ValueSource(nameof(_F_Cvt_Z_SU_Gp_Fixed_SX_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1S_F_WX_))] ulong a,
[Values(1u, 64u)] uint fBits)
{
@@ -477,10 +487,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_Z_SU_Gp_Fixed_DW([ValueSource(nameof(_F_Cvt_Z_SU_Gp_Fixed_DW_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1D_F_WX_))] ulong a,
[Values(1u, 32u)] uint fBits)
{
@@ -498,10 +509,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_Z_SU_Gp_Fixed_DX([ValueSource(nameof(_F_Cvt_Z_SU_Gp_Fixed_DX_))] uint opcodes,
[Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1D_F_WX_))] ulong a,
[Values(1u, 64u)] uint fBits)
{
@@ -518,16 +530,17 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_WS([ValueSource(nameof(_SU_Cvt_F_Gp_WS_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_W_))] uint wn)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE0E1(z, z);
SingleOpcode(opcodes, x1: wn, x31: w31, v0: v0);
@@ -535,16 +548,17 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_WD([ValueSource(nameof(_SU_Cvt_F_Gp_WD_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_W_))] uint wn)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE1(z);
SingleOpcode(opcodes, x1: wn, x31: w31, v0: v0);
@@ -552,16 +566,17 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_XS([ValueSource(nameof(_SU_Cvt_F_Gp_XS_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_X_))] ulong xn)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
ulong x31 = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE0E1(z, z);
SingleOpcode(opcodes, x1: xn, x31: x31, v0: v0);
@@ -569,16 +584,17 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_XD([ValueSource(nameof(_SU_Cvt_F_Gp_XD_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_X_))] ulong xn)
{
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
ulong x31 = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE1(z);
SingleOpcode(opcodes, x1: xn, x31: x31, v0: v0);
@@ -586,9 +602,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_Fixed_WS([ValueSource(nameof(_SU_Cvt_F_Gp_Fixed_WS_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_W_))] uint wn,
[Values(1u, 32u)] uint fBits)
@@ -598,8 +615,8 @@ namespace Ryujinx.Tests.Cpu
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= (scale << 10);
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE0E1(z, z);
SingleOpcode(opcodes, x1: wn, x31: w31, v0: v0);
@@ -607,9 +624,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_Fixed_WD([ValueSource(nameof(_SU_Cvt_F_Gp_Fixed_WD_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_W_))] uint wn,
[Values(1u, 32u)] uint fBits)
@@ -619,8 +637,8 @@ namespace Ryujinx.Tests.Cpu
opcodes |= ((rn & 31) << 5) | ((rd & 31) << 0);
opcodes |= (scale << 10);
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE1(z);
SingleOpcode(opcodes, x1: wn, x31: w31, v0: v0);
@@ -628,9 +646,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_Fixed_XS([ValueSource(nameof(_SU_Cvt_F_Gp_Fixed_XS_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_X_))] ulong xn,
[Values(1u, 64u)] uint fBits)
@@ -641,7 +660,7 @@ namespace Ryujinx.Tests.Cpu
opcodes |= (scale << 10);
ulong x31 = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE0E1(z, z);
SingleOpcode(opcodes, x1: xn, x31: x31, v0: v0);
@@ -649,9 +668,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_Gp_Fixed_XD([ValueSource(nameof(_SU_Cvt_F_Gp_Fixed_XD_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_X_))] ulong xn,
[Values(1u, 64u)] uint fBits)
@@ -662,7 +682,7 @@ namespace Ryujinx.Tests.Cpu
opcodes |= (scale << 10);
ulong x31 = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE1(z);
SingleOpcode(opcodes, x1: xn, x31: x31, v0: v0);
@@ -671,4 +691,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -12,7 +12,7 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdCvt32
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Vrint_AMNP_V_F32_()
{
return new[]
@@ -20,16 +20,18 @@ namespace Ryujinx.Tests.Cpu
0xf3ba0500u, // VRINTA.F32 Q0, Q0
0xf3ba0680u, // VRINTM.F32 Q0, Q0
0xf3ba0400u, // VRINTN.F32 Q0, Q0
0xf3ba0780u // VRINTP.F32 Q0, Q0
0xf3ba0780u, // VRINTP.F32 Q0, Q0
};
}
#endregion
#endregion
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static uint[] _1S_()
{
return new[] { 0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu };
return new[] {
0x00000000u, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu,
};
}
private static IEnumerable<ulong> _1S_F_()
@@ -43,19 +45,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -85,19 +87,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x007FFFFF007FFFFFul; // +Max Subnormal
yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFF800000FF800000ul; // -Infinity
yield return 0x7F8000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload)
@@ -126,19 +128,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@@ -155,13 +157,13 @@ namespace Ryujinx.Tests.Cpu
yield return rnd2;
}
}
#endregion
#endregion
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Explicit]
[Test, Pairwise, Description("VCVT.<dt>.F32 <Sd>, <Sm>")]
@@ -275,7 +277,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void Vrint_AMNP_V_F32([ValueSource(nameof(_Vrint_AMNP_V_F32_))] uint opcode,
[Values(0u, 1u, 2u, 3u)] uint rd,
[Values(0u, 1u, 2u, 3u)] uint rm,
@@ -289,12 +292,14 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rm >>= 1;
rm <<= 1;
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(d0, d1);
V128 v1 = MakeVectorE0E1(d2, d3);
@@ -508,4 +513,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -10,16 +10,18 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdExt
#region "ValueSource"
#region "ValueSource"
private static ulong[] _8B_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul,
};
}
#endregion
#endregion
[Test, Pairwise, Description("EXT <Vd>.8B, <Vn>.8B, <Vm>.8B, #<index>")]
public void Ext_V_8B([Values(0u)] uint rd,
public void Ext_V_8B([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z,
@@ -43,7 +45,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("EXT <Vd>.16B, <Vn>.16B, <Vm>.16B, #<index>")]
public void Ext_V_16B([Values(0u)] uint rd,
public void Ext_V_16B([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z,
@@ -67,4 +69,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdFcond
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static IEnumerable<ulong> _1S_F_()
{
yield return 0x00000000FF7FFFFFul; // -Max Normal (float.MinValue)
@@ -23,19 +23,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -65,19 +65,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@@ -94,15 +94,15 @@ namespace Ryujinx.Tests.Cpu
yield return rnd2;
}
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _F_Ccmp_Ccmpe_S_S_()
{
return new[]
{
0x1E220420u, // FCCMP S1, S2, #0, EQ
0x1E220430u // FCCMPE S1, S2, #0, EQ
0x1E220430u, // FCCMPE S1, S2, #0, EQ
};
}
@@ -111,7 +111,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x1E620420u, // FCCMP D1, D2, #0, EQ
0x1E620430u // FCCMPE D1, D2, #0, EQ
0x1E620430u, // FCCMPE D1, D2, #0, EQ
};
}
@@ -119,7 +119,7 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x1E220C20u // FCSEL S0, S1, S2, EQ
0x1E220C20u, // FCSEL S0, S1, S2, EQ
};
}
@@ -127,19 +127,20 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x1E620C20u // FCSEL D0, D1, D2, EQ
0x1E620C20u, // FCSEL D0, D1, D2, EQ
};
}
#endregion
#endregion
private const int RndCnt = 2;
private const int RndCnt = 2;
private const int RndCntNzcv = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Ccmp_Ccmpe_S_S([ValueSource(nameof(_F_Ccmp_Ccmpe_S_S_))] uint opcodes,
[ValueSource(nameof(_1S_F_))] ulong a,
[ValueSource(nameof(_1S_F_))] ulong b,
@@ -164,7 +165,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc);
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Ccmp_Ccmpe_S_D([ValueSource(nameof(_F_Ccmp_Ccmpe_S_D_))] uint opcodes,
[ValueSource(nameof(_1D_F_))] ulong a,
[ValueSource(nameof(_1D_F_))] ulong b,
@@ -189,7 +191,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc);
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Csel_S_S([ValueSource(nameof(_F_Csel_S_S_))] uint opcodes,
[ValueSource(nameof(_1S_F_))] ulong a,
[ValueSource(nameof(_1S_F_))] ulong b,
@@ -210,7 +213,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Csel_S_D([ValueSource(nameof(_F_Csel_S_D_))] uint opcodes,
[ValueSource(nameof(_1D_F_))] ulong a,
[ValueSource(nameof(_1D_F_))] ulong b,

View File

@@ -10,12 +10,12 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdFmov
#region "ValueSource"
#region "ValueSource"
private static uint[] _F_Mov_Si_S_()
{
return new[]
{
0x1E201000u // FMOV S0, #2.0
0x1E201000u, // FMOV S0, #2.0
};
}
@@ -23,12 +23,13 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x1E601000u // FMOV D0, #2.0
0x1E601000u, // FMOV D0, #2.0
};
}
#endregion
#endregion
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mov_Si_S([ValueSource(nameof(_F_Mov_Si_S_))] uint opcodes,
[Range(0u, 255u, 1u)] uint imm8)
{
@@ -42,7 +43,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mov_Si_D([ValueSource(nameof(_F_Mov_Si_D_))] uint opcodes,
[Range(0u, 255u, 1u)] uint imm8)
{

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdImm
#region "Helper methods"
#region "Helper methods"
// abcdefgh -> aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh
private static ulong ExpandImm8(byte imm8)
{
@@ -43,19 +43,23 @@ namespace Ryujinx.Tests.Cpu
return imm8;
}
#endregion
#endregion
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _2S_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _4H_()
{
return new[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static IEnumerable<byte> _8BIT_IMM_()
@@ -87,15 +91,15 @@ namespace Ryujinx.Tests.Cpu
yield return ExpandImm8(imm8);
}
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Bic_Orr_Vi_16bit_()
{
return new[]
{
0x2F009400u, // BIC V0.4H, #0
0x0F009400u // ORR V0.4H, #0
0x0F009400u, // ORR V0.4H, #0
};
}
@@ -104,7 +108,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x2F001400u, // BIC V0.2S, #0
0x0F001400u // ORR V0.2S, #0
0x0F001400u, // ORR V0.2S, #0
};
}
@@ -112,7 +116,7 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x0F00F400u // FMOV V0.2S, #2.0
0x0F00F400u, // FMOV V0.2S, #2.0
};
}
@@ -120,7 +124,7 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x4F00F400u // FMOV V0.4S, #2.0
0x4F00F400u, // FMOV V0.4S, #2.0
};
}
@@ -128,7 +132,7 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x6F00F400u // FMOV V0.2D, #2.0
0x6F00F400u, // FMOV V0.2D, #2.0
};
}
@@ -136,7 +140,7 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x0F00E400u // MOVI V0.8B, #0
0x0F00E400u, // MOVI V0.8B, #0
};
}
@@ -145,7 +149,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F008400u, // MOVI V0.4H, #0
0x2F008400u // MVNI V0.4H, #0
0x2F008400u, // MVNI V0.4H, #0
};
}
@@ -154,7 +158,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F000400u, // MOVI V0.2S, #0
0x2F000400u // MVNI V0.2S, #0
0x2F000400u, // MVNI V0.2S, #0
};
}
@@ -163,7 +167,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F00C400u, // MOVI V0.2S, #0, MSL #8
0x2F00C400u // MVNI V0.2S, #0, MSL #8
0x2F00C400u, // MVNI V0.2S, #0, MSL #8
};
}
@@ -171,7 +175,7 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x2F00E400u // MOVI D0, #0
0x2F00E400u, // MOVI D0, #0
};
}
@@ -179,12 +183,12 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0x6F00E400u // MOVI V0.2D, #0
0x6F00E400u, // MOVI V0.2D, #0
};
}
#endregion
#endregion
private const int RndCntImm8 = 2;
private const int RndCntImm8 = 2;
private const int RndCntImm64 = 2;
[Test, Pairwise]
@@ -194,7 +198,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0b0u, 0b1u)] uint amount, // <0, 8>
[Values(0b0u, 0b1u)] uint q) // <4H, 8H>
{
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -215,7 +219,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0b00u, 0b01u, 0b10u, 0b11u)] uint amount, // <0, 8, 16, 24>
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
{
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -229,11 +233,12 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mov_Vi_2S([ValueSource(nameof(_F_Mov_Vi_2S_))] uint opcodes,
[Range(0u, 255u, 1u)] uint abcdefgh)
{
uint abc = (abcdefgh & 0xE0u) >> 5;
uint abc = (abcdefgh & 0xE0u) >> 5;
uint defgh = (abcdefgh & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -246,11 +251,12 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mov_Vi_4S([ValueSource(nameof(_F_Mov_Vi_4S_))] uint opcodes,
[Range(0u, 255u, 1u)] uint abcdefgh)
{
uint abc = (abcdefgh & 0xE0u) >> 5;
uint abc = (abcdefgh & 0xE0u) >> 5;
uint defgh = (abcdefgh & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -260,11 +266,12 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mov_Vi_2D([ValueSource(nameof(_F_Mov_Vi_2D_))] uint opcodes,
[Range(0u, 255u, 1u)] uint abcdefgh)
{
uint abc = (abcdefgh & 0xE0u) >> 5;
uint abc = (abcdefgh & 0xE0u) >> 5;
uint defgh = (abcdefgh & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -279,7 +286,7 @@ namespace Ryujinx.Tests.Cpu
[ValueSource(nameof(_8BIT_IMM_))] byte imm8,
[Values(0b0u, 0b1u)] uint q) // <8B, 16B>
{
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -299,7 +306,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0b0u, 0b1u)] uint amount, // <0, 8>
[Values(0b0u, 0b1u)] uint q) // <4H, 8H>
{
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -320,7 +327,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0b00u, 0b01u, 0b10u, 0b11u)] uint amount, // <0, 8, 16, 24>
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
{
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -341,7 +348,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0b0u, 0b1u)] uint amount, // <8, 16>
[Values(0b0u, 0b1u)] uint q) // <2S, 4S>
{
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -362,7 +369,7 @@ namespace Ryujinx.Tests.Cpu
{
byte imm8 = ShrinkImm64(imm);
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -381,7 +388,7 @@ namespace Ryujinx.Tests.Cpu
{
byte imm8 = ShrinkImm64(imm);
uint abc = (imm8 & 0xE0u) >> 5;
uint abc = (imm8 & 0xE0u) >> 5;
uint defgh = (imm8 & 0x1Fu);
opcodes |= (abc << 16) | (defgh << 5);
@@ -392,4 +399,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -10,64 +10,80 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdIns
#region "ValueSource"
#region "ValueSource"
private static ulong[] _1D_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _2S_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _4H_()
{
return new[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _8B_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _8B4H_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _8B4H2S_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static uint[] _W_()
{
return new[] { 0x00000000u, 0x0000007Fu,
0x00000080u, 0x000000FFu,
0x00007FFFu, 0x00008000u,
0x0000FFFFu, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu };
return new[] {
0x00000000u, 0x0000007Fu,
0x00000080u, 0x000000FFu,
0x00007FFFu, 0x00008000u,
0x0000FFFFu, 0x7FFFFFFFu,
0x80000000u, 0xFFFFFFFFu,
};
}
private static ulong[] _X_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
#endregion
#endregion
[Test, Pairwise, Description("DUP <Vd>.<T>, W<n>")]
public void Dup_Gp_W([Values(0u)] uint rd,
public void Dup_Gp_W([Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_W_))] uint wn,
[Values(0, 1, 2)] int size, // Q0: <8B, 4H, 2S>
@@ -80,8 +96,8 @@ namespace Ryujinx.Tests.Cpu
opcode |= (imm5 << 16);
opcode |= ((q & 1) << 30);
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
uint w31 = TestContext.CurrentContext.Random.NextUInt();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE0E1(z, z);
SingleOpcode(opcode, x1: wn, x31: w31, v0: v0);
@@ -90,7 +106,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("DUP <Vd>.<T>, X<n>")]
public void Dup_Gp_X([Values(0u)] uint rd,
public void Dup_Gp_X([Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_X_))] ulong xn)
{
@@ -98,7 +114,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((rn & 31) << 5) | ((rd & 31) << 0);
ulong x31 = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
ulong z = TestContext.CurrentContext.Random.NextULong();
V128 v0 = MakeVectorE0E1(z, z);
SingleOpcode(opcode, x1: xn, x31: x31, v0: v0);
@@ -187,7 +203,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.B[<index>]")]
public void Dup_V_8B_16B([Values(0u)] uint rd,
public void Dup_V_8B_16B([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a,
@@ -212,7 +228,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.H[<index>]")]
public void Dup_V_4H_8H([Values(0u)] uint rd,
public void Dup_V_4H_8H([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
@@ -237,7 +253,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.S[<index>]")]
public void Dup_V_2S_4S([Values(0u)] uint rd,
public void Dup_V_2S_4S([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -262,7 +278,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("DUP <Vd>.<T>, <Vn>.D[<index>]")]
public void Dup_V_2D([Values(0u)] uint rd,
public void Dup_V_2D([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -287,7 +303,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.B[<index>], W<n>")]
public void Ins_Gp_WB([Values(0u)] uint rd,
public void Ins_Gp_WB([Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_W_))] uint wn,
@@ -310,7 +326,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.H[<index>], W<n>")]
public void Ins_Gp_WH([Values(0u)] uint rd,
public void Ins_Gp_WH([Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_W_))] uint wn,
@@ -333,7 +349,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.S[<index>], W<n>")]
public void Ins_Gp_WS([Values(0u)] uint rd,
public void Ins_Gp_WS([Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_W_))] uint wn,
@@ -356,7 +372,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.D[<index>], X<n>")]
public void Ins_Gp_XD([Values(0u)] uint rd,
public void Ins_Gp_XD([Values(0u)] uint rd,
[Values(1u, 31u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_X_))] ulong xn,
@@ -379,7 +395,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.B[<index1>], <Vn>.B[<index2>]")]
public void Ins_V_BB([Values(0u)] uint rd,
public void Ins_V_BB([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a,
@@ -405,7 +421,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.H[<index1>], <Vn>.H[<index2>]")]
public void Ins_V_HH([Values(0u)] uint rd,
public void Ins_V_HH([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
@@ -431,7 +447,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.S[<index1>], <Vn>.S[<index2>]")]
public void Ins_V_SS([Values(0u)] uint rd,
public void Ins_V_SS([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -457,7 +473,7 @@ namespace Ryujinx.Tests.Cpu
}
[Test, Pairwise, Description("INS <Vd>.D[<index1>], <Vn>.D[<index2>]")]
public void Ins_V_DD([Values(0u)] uint rd,
public void Ins_V_DD([Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -484,7 +500,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("SMOV <Wd>, <Vn>.B[<index>]")]
public void Smov_S_BW([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_8B_))] ulong a,
[Values(0u, 15u)] uint index)
{
@@ -507,7 +523,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("SMOV <Wd>, <Vn>.H[<index>]")]
public void Smov_S_HW([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_4H_))] ulong a,
[Values(0u, 7u)] uint index)
{
@@ -530,7 +546,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("SMOV <Xd>, <Vn>.B[<index>]")]
public void Smov_S_BX([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_8B_))] ulong a,
[Values(0u, 15u)] uint index)
{
@@ -552,7 +568,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("SMOV <Xd>, <Vn>.H[<index>]")]
public void Smov_S_HX([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_4H_))] ulong a,
[Values(0u, 7u)] uint index)
{
@@ -574,7 +590,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("SMOV <Xd>, <Vn>.S[<index>]")]
public void Smov_S_SX([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_2S_))] ulong a,
[Values(0u, 1u, 2u, 3u)] uint index)
{
@@ -596,7 +612,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("UMOV <Wd>, <Vn>.B[<index>]")]
public void Umov_S_BW([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_8B_))] ulong a,
[Values(0u, 15u)] uint index)
{
@@ -619,7 +635,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("UMOV <Wd>, <Vn>.H[<index>]")]
public void Umov_S_HW([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_4H_))] ulong a,
[Values(0u, 7u)] uint index)
{
@@ -642,7 +658,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("UMOV <Wd>, <Vn>.S[<index>]")]
public void Umov_S_SW([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_2S_))] ulong a,
[Values(0u, 1u, 2u, 3u)] uint index)
{
@@ -665,7 +681,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise, Description("UMOV <Xd>, <Vn>.D[<index>]")]
public void Umov_S_DX([Values(0u, 31u)] uint rd,
[Values(1u)] uint rn,
[Values(1u)] uint rn,
[ValueSource(nameof(_1D_))] ulong a,
[Values(0u, 1u)] uint index)
{

View File

@@ -10,17 +10,19 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdLogical32
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _8B4H2S_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Vbic_Vbif_Vbit_Vbsl_Vand_Vorn_Vorr_Veor_I_()
{
return new[]
@@ -32,7 +34,7 @@ namespace Ryujinx.Tests.Cpu
0xf2000110u, // VAND D0, D0, D0
0xf2300110u, // VORN D0, D0, D0
0xf2200110u, // VORR D0, D0, D0
0xf3000110u // VEOR D0, D0, D0
0xf3000110u, // VEOR D0, D0, D0
};
}
@@ -43,10 +45,10 @@ namespace Ryujinx.Tests.Cpu
0xf2800130u, // VBIC.I32 D0, #0 (A1)
0xf2800930u, // VBIC.I16 D0, #0 (A2)
0xf2800110u, // VORR.I32 D0, #0 (A1)
0xf2800910u // VORR.I16 D0, #0 (A2)
0xf2800910u, // VORR.I16 D0, #0 (A2)
};
}
#endregion
#endregion
[Test, Pairwise]
public void Vbic_Vbif_Vbit_Vbsl_Vand_Vorn_Vorr_Veor_I([ValueSource(nameof(_Vbic_Vbif_Vbit_Vbsl_Vand_Vorn_Vorr_Veor_I_))] uint opcode,
@@ -62,14 +64,17 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rn >>= 1; rn <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rn >>= 1;
rn <<= 1;
rm >>= 1;
rm <<= 1;
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(z, ~z);
V128 v1 = MakeVectorE0E1(a, ~a);
@@ -97,10 +102,11 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rd >>= 1;
rd <<= 1;
}
opcode |= ((uint)imm & 0xf) << 0;
opcode |= ((uint)imm & 0xf) << 0;
opcode |= ((uint)imm & 0x70) << 12;
opcode |= ((uint)imm & 0x80) << 17;
opcode |= (cMode & 0x3) << 9;
@@ -129,14 +135,17 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rn >>= 1; rn <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rn >>= 1;
rn <<= 1;
rm >>= 1;
rm <<= 1;
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= (size & 0x3) << 20;
@@ -150,4 +159,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -10,10 +10,10 @@ namespace Ryujinx.Tests.Cpu
[Category("SimdMemory32")]
public sealed class CpuTestSimdMemory32 : CpuTest32
{
private static readonly uint TestOffset = DataBaseAddress + 0x500;
private static readonly uint _testOffset = DataBaseAddress + 0x500;
#if SimdMemory32
private uint[] _ldStModes =
private readonly uint[] _ldStModes =
{
// LD1
0b0111,
@@ -32,7 +32,7 @@ namespace Ryujinx.Tests.Cpu
// LD4
0b0000,
0b0001
0b0001,
};
[Test, Pairwise, Description("VLDn.<size> <list>, [<Rn> {:<align>}]{ /!/, <Rm>} (single n element structure)")]
@@ -51,16 +51,16 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((size & 3) << 10) | ((rn & 15) << 16) | (rm & 15);
uint index_align = (index << (int)(1 + size)) & 15;
uint indexAlign = (index << (int)(1 + size)) & 15;
opcode |= (index_align) << 4;
opcode |= (indexAlign) << 4;
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
SingleOpcode(opcode, r0: _testOffset, r1: offset, sp: _testOffset);
CompareAgainstUnicorn();
}
@@ -85,9 +85,12 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0xf) << 12);
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
if (t) opcode |= 1 << 5;
if (t)
{
opcode |= 1 << 5;
}
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
SingleOpcode(opcode, r0: _testOffset, r1: offset, sp: _testOffset);
CompareAgainstUnicorn();
}
@@ -116,7 +119,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
SingleOpcode(opcode, r0: _testOffset, r1: offset, sp: _testOffset);
CompareAgainstUnicorn();
}
@@ -139,16 +142,16 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((size & 3) << 10) | ((rn & 15) << 16) | (rm & 15);
uint index_align = (index << (int)(1 + size)) & 15;
uint indexAlign = (index << (int)(1 + size)) & 15;
opcode |= (index_align) << 4;
opcode |= (indexAlign) << 4;
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc.
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
SingleOpcode(opcode, r0: _testOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: _testOffset);
CompareAgainstUnicorn();
}
@@ -179,7 +182,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
SingleOpcode(opcode, r0: _testOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: _testOffset);
CompareAgainstUnicorn();
}
@@ -201,7 +204,7 @@ namespace Ryujinx.Tests.Cpu
// Note: 3rd 0 leaves a space for "D".
0b0100, // Increment after.
0b0101, // Increment after. (!)
0b1001 // Decrement before. (!)
0b1001, // Decrement before. (!)
};
opcode |= ((vldmModes[mode] & 15) << 21);
@@ -212,7 +215,11 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((uint)(single ? 0 : 1) << 8);
if (!single) regs = (regs << 1); // Low bit must be 0 - must be even number of registers.
if (!single)
{
regs <<= 1; // Low bit must be 0 - must be even number of registers.
}
uint regSize = single ? 1u : 2u;
if (vd + (regs / regSize) > 32) // Can't address further than S31 or D31.
@@ -227,7 +234,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= regs & 0xff;
SingleOpcode(opcode, r0: TestOffset, sp: TestOffset);
SingleOpcode(opcode, r0: _testOffset, sp: _testOffset);
CompareAgainstUnicorn();
}
@@ -262,7 +269,7 @@ namespace Ryujinx.Tests.Cpu
}
opcode |= imm & 0xff;
SingleOpcode(opcode, r0: TestOffset);
SingleOpcode(opcode, r0: _testOffset);
CompareAgainstUnicorn();
}
@@ -299,12 +306,12 @@ namespace Ryujinx.Tests.Cpu
(V128 vec1, V128 vec2, _, _) = GenerateTestVectors();
SingleOpcode(opcode, r0: TestOffset, v0: vec1, v1: vec2);
SingleOpcode(opcode, r0: _testOffset, v0: vec1, v1: vec2);
CompareAgainstUnicorn();
}
private (V128, V128, V128, V128) GenerateTestVectors()
private static (V128, V128, V128, V128) GenerateTestVectors()
{
return (
new V128(-12.43f, 1872.23f, 4456.23f, -5622.2f),
@@ -314,7 +321,7 @@ namespace Ryujinx.Tests.Cpu
);
}
private byte[] GenerateVectorSequence(int length)
private static byte[] GenerateVectorSequence(int length)
{
int floatLength = length >> 2;
float[] data = new float[floatLength];
@@ -330,4 +337,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -35,7 +35,7 @@ namespace Ryujinx.Tests.Cpu
0b1110_0,
0b1111_0,
0b1110_1
0b1110_1,
};
uint opcode = 0xf2800010u; // VMOV.I32 D0, #0
@@ -97,7 +97,10 @@ namespace Ryujinx.Tests.Cpu
opcode |= (vn & 0x1e) << 15;
opcode |= (rt & 0xf) << 12;
if (op) opcode |= 1 << 20;
if (op)
{
opcode |= 1 << 20;
}
SingleOpcode(opcode, r0: valueRn, r1: valueRn, r2: valueRn, r3: valueRn, v0: new V128(valueVn1, valueVn2));
@@ -217,10 +220,10 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
V128 v0 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v0 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3);
@@ -247,10 +250,10 @@ namespace Ryujinx.Tests.Cpu
opcode |= 1 << 24;
}
V128 v0 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v0 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3);
@@ -279,10 +282,10 @@ namespace Ryujinx.Tests.Cpu
opcode |= (vd & 0x10) << 18;
opcode |= (vd & 0xf) << 12;
V128 v0 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v0 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3);
@@ -348,18 +351,20 @@ namespace Ryujinx.Tests.Cpu
if (q)
{
opcode |= 1 << 6;
vd <<= 1; vm <<= 1;
vd <<= 1;
vm <<= 1;
}
opcode |= (vm & 0x10) << 1;
opcode |= (vm & 0xf);
opcode |= (vd & 0x10) << 18;
opcode |= (vd & 0xf) << 12;
opcode |= (size & 0x3) << 18;
V128 v0 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v0 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3);
@@ -381,18 +386,20 @@ namespace Ryujinx.Tests.Cpu
if (q)
{
opcode |= 1 << 6;
vd <<= 1; vm <<= 1;
vd <<= 1;
vm <<= 1;
}
opcode |= (vm & 0x10) << 1;
opcode |= (vm & 0xf);
opcode |= (vd & 0x10) << 18;
opcode |= (vd & 0xf) << 12;
opcode |= (size & 0x3) << 18;
V128 v0 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v0 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3);
@@ -414,18 +421,20 @@ namespace Ryujinx.Tests.Cpu
if (q)
{
opcode |= 1 << 6;
vd <<= 1; vm <<= 1;
vd <<= 1;
vm <<= 1;
}
opcode |= (vm & 0x10) << 1;
opcode |= (vm & 0xf);
opcode |= (vd & 0x10) << 18;
opcode |= (vd & 0xf) << 12;
opcode |= (size & 0x3) << 18;
V128 v0 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v0 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3);
@@ -459,22 +468,22 @@ namespace Ryujinx.Tests.Cpu
opcode |= (length & 0x3) << 8;
var rnd = TestContext.CurrentContext.Random;
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v4 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v5 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v4 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v5 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
byte maxIndex = (byte)(length * 8 - 1);
byte[] b0 = new byte[16];
byte[] b1 = new byte[16];
for (int i=0; i<16; i++)
for (int i = 0; i < 16; i++)
{
b0[i] = rnd.NextByte(maxIndex);
b1[i] = rnd.NextByte(maxIndex);
}
V128 v0 = new V128(b0);
V128 v1 = new V128(b1);
V128 v0 = new(b0);
V128 v1 = new(b1);
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3, v4: v4, v5: v5);
@@ -493,7 +502,9 @@ namespace Ryujinx.Tests.Cpu
if (q)
{
opcode |= 1 << 6;
vd <<= 1; vm <<= 1; vn <<= 1;
vd <<= 1;
vm <<= 1;
vn <<= 1;
}
else if (imm4 > 7)
{
@@ -507,10 +518,10 @@ namespace Ryujinx.Tests.Cpu
opcode |= (vn & 0xf) << 16;
opcode |= (imm4 & 0xf) << 8;
V128 v0 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v0 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: v0, v1: v1, v2: v2, v3: v3);
@@ -541,7 +552,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= (size & 1) << 5; // E
opcode |= (size & 2) << 21; // B
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, r0: valueRn, r1: valueRn, r2: valueRn, r3: valueRn, v0: new V128(valueVn1, valueVn2), v1: v1);
@@ -586,9 +597,9 @@ namespace Ryujinx.Tests.Cpu
opcode |= imm4 << 16;
V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v1 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v2 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
V128 v3 = new(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong());
SingleOpcode(opcode, v0: new V128(valueVn1, valueVn2), v1: v1, v2: v2, v3: v3);
@@ -596,4 +607,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdReg32
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _V_Add_Sub_Long_Wide_I_()
{
return new[]
@@ -20,7 +20,7 @@ namespace Ryujinx.Tests.Cpu
0xf2800000u, // VADDL.S8 Q0, D0, D0
0xf2800100u, // VADDW.S8 Q0, Q0, D0
0xf2800200u, // VSUBL.S8 Q0, D0, D0
0xf2800300u // VSUBW.S8 Q0, Q0, D0
0xf2800300u, // VSUBW.S8 Q0, Q0, D0
};
}
@@ -31,7 +31,7 @@ namespace Ryujinx.Tests.Cpu
0xEEA00A00u, // VFMA. F32 S0, S0, S0
0xEEA00A40u, // VFMS. F32 S0, S0, S0
0xEE900A40u, // VFNMA.F32 S0, S0, S0
0xEE900A00u // VFNMS.F32 S0, S0, S0
0xEE900A00u, // VFNMS.F32 S0, S0, S0
};
}
@@ -42,7 +42,7 @@ namespace Ryujinx.Tests.Cpu
0xEEA00B00u, // VFMA. F64 D0, D0, D0
0xEEA00B40u, // VFMS. F64 D0, D0, D0
0xEE900B40u, // VFNMA.F64 D0, D0, D0
0xEE900B00u // VFNMS.F64 D0, D0, D0
0xEE900B00u, // VFNMS.F64 D0, D0, D0
};
}
@@ -51,7 +51,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0xF2000C10u, // VFMA.F32 D0, D0, D0
0xF2200C10u // VFMS.F32 D0, D0, D0
0xF2200C10u, // VFMS.F32 D0, D0, D0
};
}
@@ -62,7 +62,7 @@ namespace Ryujinx.Tests.Cpu
0xEE000A00u, // VMLA. F32 S0, S0, S0
0xEE000A40u, // VMLS. F32 S0, S0, S0
0xEE100A40u, // VNMLA.F32 S0, S0, S0
0xEE100A00u // VNMLS.F32 S0, S0, S0
0xEE100A00u, // VNMLS.F32 S0, S0, S0
};
}
@@ -73,7 +73,7 @@ namespace Ryujinx.Tests.Cpu
0xEE000B00u, // VMLA. F64 D0, D0, D0
0xEE000B40u, // VMLS. F64 D0, D0, D0
0xEE100B40u, // VNMLA.F64 D0, D0, D0
0xEE100B00u // VNMLS.F64 D0, D0, D0
0xEE100B00u, // VNMLS.F64 D0, D0, D0
};
}
@@ -82,7 +82,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0xf2800800u, // VMLAL.S8 Q0, D0, D0
0xf2800a00u // VMLSL.S8 Q0, D0, D0
0xf2800a00u, // VMLSL.S8 Q0, D0, D0
};
}
@@ -92,7 +92,7 @@ namespace Ryujinx.Tests.Cpu
{
0xf3000d00u, // VPADD.F32 D0, D0, D0
0xf3000f00u, // VPMAX.F32 D0, D0, D0
0xf3200f00u // VPMIN.F32 D0, D0, D0
0xf3200f00u, // VPMIN.F32 D0, D0, D0
};
}
@@ -100,7 +100,7 @@ namespace Ryujinx.Tests.Cpu
{
return new[]
{
0xf2000b10u // VPADD.I8 D0, D0, D0
0xf2000b10u, // VPADD.I8 D0, D0, D0
};
}
@@ -119,26 +119,30 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0xf2000050u, // VQADD.S8 Q0, Q0, Q0
0xf2000250u // VQSUB.S8 Q0, Q0, Q0
0xf2000250u, // VQSUB.S8 Q0, Q0, Q0
};
}
#endregion
#endregion
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _8B1D_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _8B4H2S1D_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static IEnumerable<ulong> _1S_F_()
@@ -152,19 +156,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -194,19 +198,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x007FFFFF007FFFFFul; // +Max Subnormal
yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFF800000FF800000ul; // -Infinity
yield return 0x7F8000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload)
@@ -235,19 +239,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@@ -264,13 +268,13 @@ namespace Ryujinx.Tests.Cpu
yield return rnd2;
}
}
#endregion
#endregion
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise, Description("SHA256H.32 <Qd>, <Qn>, <Qm>")]
public void Sha256h_V([Values(0xF3000C40u)] uint opcode,
@@ -288,7 +292,7 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(z0, z1);
V128 v1 = MakeVectorE0E1(a0, a1);
@@ -322,7 +326,7 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(z0, z1);
V128 v1 = MakeVectorE0E1(a0, a1);
@@ -356,7 +360,7 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(z0, z1);
V128 v1 = MakeVectorE0E1(a0, a1);
@@ -396,7 +400,7 @@ namespace Ryujinx.Tests.Cpu
rd <<= 1;
}
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
@@ -425,12 +429,14 @@ namespace Ryujinx.Tests.Cpu
opcode |= 1 << 24;
}
rd >>= 1; rd <<= 1;
rn >>= 1; rn <<= 1;
rd >>= 1;
rd <<= 1;
rn >>= 1;
rn <<= 1;
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= (size & 0x3) << 20;
@@ -455,12 +461,12 @@ namespace Ryujinx.Tests.Cpu
if (size == 3)
{
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
}
else
{
opcode |= ((rm & 0x1e) >> 1) | ((rm & 0x1) << 5);
opcode |= ((rm & 0x1e) >> 1) | ((rm & 0x1) << 5);
opcode |= ((rd & 0x1e) << 11) | ((rd & 0x1) << 22);
}
@@ -480,7 +486,9 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(fpsrMask: Fpsr.Nzcv);
}
[Test, Pairwise] [Explicit] // Fused.
// Fused.
[Test, Pairwise]
[Explicit]
public void Vfma_Vfms_Vfnma_Vfnms_S_F32([ValueSource(nameof(_Vfma_Vfms_Vfnma_Vfnms_S_F32_))] uint opcode,
[Values(0u, 1u, 2u, 3u)] uint rd,
[Values(0u, 1u, 2u, 3u)] uint rn,
@@ -491,8 +499,8 @@ namespace Ryujinx.Tests.Cpu
[ValueSource(nameof(_1S_F_))] ulong s3)
{
opcode |= (((rd & 0x1) << 22) | (rd & 0x1e) << 11);
opcode |= (((rn & 0x1) << 7) | (rn & 0x1e) << 15);
opcode |= (((rm & 0x1) << 5) | (rm & 0x1e) >> 1);
opcode |= (((rn & 0x1) << 7) | (rn & 0x1e) << 15);
opcode |= (((rm & 0x1) << 5) | (rm & 0x1e) >> 1);
V128 v0 = MakeVectorE0E1E2E3((uint)s0, (uint)s1, (uint)s2, (uint)s3);
@@ -501,7 +509,9 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit] // Fused.
// Fused.
[Test, Pairwise]
[Explicit]
public void Vfma_Vfms_Vfnma_Vfnms_S_F64([ValueSource(nameof(_Vfma_Vfms_Vfnma_Vfnms_S_F64_))] uint opcode,
[Values(0u, 1u)] uint rd,
[Values(0u, 1u)] uint rn,
@@ -510,8 +520,8 @@ namespace Ryujinx.Tests.Cpu
[ValueSource(nameof(_1D_F_))] ulong d1)
{
opcode |= (((rd & 0x10) << 18) | (rd & 0xf) << 12);
opcode |= (((rn & 0x10) << 3) | (rn & 0xf) << 16);
opcode |= (((rm & 0x10) << 1) | (rm & 0xf) << 0);
opcode |= (((rn & 0x10) << 3) | (rn & 0xf) << 16);
opcode |= (((rm & 0x10) << 1) | (rm & 0xf) << 0);
V128 v0 = MakeVectorE0E1(d0, d1);
@@ -520,7 +530,9 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit] // Fused.
// Fused.
[Test, Pairwise]
[Explicit]
public void Vfma_Vfms_V_F32([ValueSource(nameof(_Vfma_Vfms_V_F32_))] uint opcode,
[Values(0u, 1u, 2u, 3u)] uint rd,
[Values(0u, 1u, 2u, 3u)] uint rn,
@@ -535,14 +547,17 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rn >>= 1; rn <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rn >>= 1;
rn <<= 1;
rm >>= 1;
rm <<= 1;
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
V128 v0 = MakeVectorE0E1(d0, d1);
V128 v1 = MakeVectorE0E1(d2, d3);
@@ -552,7 +567,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void Vmla_Vmls_Vnmla_Vnmls_S_F32([ValueSource(nameof(_Vmla_Vmls_Vnmla_Vnmls_S_F32_))] uint opcode,
[Values(0u, 1u, 2u, 3u)] uint rd,
[Values(0u, 1u, 2u, 3u)] uint rn,
@@ -563,8 +579,8 @@ namespace Ryujinx.Tests.Cpu
[ValueSource(nameof(_1S_F_))] ulong s3)
{
opcode |= (((rd & 0x1) << 22) | (rd & 0x1e) << 11);
opcode |= (((rn & 0x1) << 7) | (rn & 0x1e) << 15);
opcode |= (((rm & 0x1) << 5) | (rm & 0x1e) >> 1);
opcode |= (((rn & 0x1) << 7) | (rn & 0x1e) << 15);
opcode |= (((rm & 0x1) << 5) | (rm & 0x1e) >> 1);
V128 v0 = MakeVectorE0E1E2E3((uint)s0, (uint)s1, (uint)s2, (uint)s3);
@@ -573,7 +589,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void Vmla_Vmls_Vnmla_Vnmls_S_F64([ValueSource(nameof(_Vmla_Vmls_Vnmla_Vnmls_S_F64_))] uint opcode,
[Values(0u, 1u)] uint rd,
[Values(0u, 1u)] uint rn,
@@ -582,8 +599,8 @@ namespace Ryujinx.Tests.Cpu
[ValueSource(nameof(_1D_F_))] ulong d1)
{
opcode |= (((rd & 0x10) << 18) | (rd & 0xf) << 12);
opcode |= (((rn & 0x10) << 3) | (rn & 0xf) << 16);
opcode |= (((rm & 0x10) << 1) | (rm & 0xf) << 0);
opcode |= (((rn & 0x10) << 3) | (rn & 0xf) << 16);
opcode |= (((rm & 0x10) << 1) | (rm & 0xf) << 0);
V128 v0 = MakeVectorE0E1(d0, d1);
@@ -603,7 +620,7 @@ namespace Ryujinx.Tests.Cpu
[Random(RndCnt)] ulong b,
[Values] bool u)
{
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
@@ -636,7 +653,7 @@ namespace Ryujinx.Tests.Cpu
{
uint opcode = 0xf2800c00u; // VMULL.S8 Q0, D0, D0
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
@@ -678,11 +695,12 @@ namespace Ryujinx.Tests.Cpu
uint opcode = 0xf2800e00u; // VMULL.P8 Q0, D0, D0
rd >>= 1; rd <<= 1;
rd >>= 1;
rd <<= 1;
opcode |= (((rd & 0x10) << 18) | (rd & 0xf) << 12);
opcode |= (((rn & 0x10) << 3) | (rn & 0xf) << 16);
opcode |= (((rm & 0x10) << 1) | (rm & 0xf) << 0);
opcode |= (((rn & 0x10) << 3) | (rn & 0xf) << 16);
opcode |= (((rm & 0x10) << 1) | (rm & 0xf) << 0);
opcode |= (size & 0x3) << 20;
@@ -723,7 +741,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= 1 << 24;
}
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
@@ -751,7 +769,7 @@ namespace Ryujinx.Tests.Cpu
[ValueSource(nameof(_2S_F_))] ulong b0,
[ValueSource(nameof(_2S_F_))] ulong b1)
{
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
@@ -774,7 +792,7 @@ namespace Ryujinx.Tests.Cpu
[Random(RndCnt)] ulong a,
[Random(RndCnt)] ulong b)
{
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
@@ -805,7 +823,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= 1 << 24;
}
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
@@ -836,13 +854,16 @@ namespace Ryujinx.Tests.Cpu
opcode |= 1 << 24;
}
rd >>= 1; rd <<= 1;
rn >>= 1; rn <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rn >>= 1;
rn <<= 1;
rm >>= 1;
rm <<= 1;
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= (size & 0x3) << 20;
@@ -864,15 +885,18 @@ namespace Ryujinx.Tests.Cpu
[ValueSource(nameof(_8B4H2S1D_))] ulong b,
[Values(1u, 2u)] uint size) // <S16, S32>
{
rd >>= 1; rd <<= 1;
rn >>= 1; rn <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rn >>= 1;
rn <<= 1;
rm >>= 1;
rm <<= 1;
uint opcode = 0xf2100b40u & ~(3u << 20); // VQDMULH.S16 Q0, Q0, Q0
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rn & 0xf) << 16) | ((rn & 0x10) << 3);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= (size & 0x3) << 20;
@@ -886,4 +910,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -10,21 +10,25 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdRegElem
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _2S_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _4H_()
{
return new[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_()
{
return new[]
@@ -33,7 +37,7 @@ namespace Ryujinx.Tests.Cpu
0x2F404000u, // MLS V0.4H, V0.4H, V0.H[0]
0x0F408000u, // MUL V0.4H, V0.4H, V0.H[0]
0x0F40C000u, // SQDMULH V0.4H, V0.4H, V0.H[0]
0x0F40D000u // SQRDMULH V0.4H, V0.4H, V0.H[0]
0x0F40D000u, // SQRDMULH V0.4H, V0.4H, V0.H[0]
};
}
@@ -45,7 +49,7 @@ namespace Ryujinx.Tests.Cpu
0x2F804000u, // MLS V0.2S, V0.2S, V0.S[0]
0x0F808000u, // MUL V0.2S, V0.2S, V0.S[0]
0x0F80C000u, // SQDMULH V0.2S, V0.2S, V0.S[0]
0x0F80D000u // SQRDMULH V0.2S, V0.2S, V0.S[0]
0x0F80D000u, // SQRDMULH V0.2S, V0.2S, V0.S[0]
};
}
@@ -58,7 +62,7 @@ namespace Ryujinx.Tests.Cpu
0x0F40A000u, // SMULL V0.4S, V0.4H, V0.H[0]
0x2F402000u, // UMLAL V0.4S, V0.4H, V0.H[0]
0x2F406000u, // UMLSL V0.4S, V0.4H, V0.H[0]
0x2F40A000u // UMULL V0.4S, V0.4H, V0.H[0]
0x2F40A000u, // UMULL V0.4S, V0.4H, V0.H[0]
};
}
@@ -71,15 +75,15 @@ namespace Ryujinx.Tests.Cpu
0x0F80A000u, // SMULL V0.2D, V0.2S, V0.S[0]
0x2F802000u, // UMLAL V0.2D, V0.2S, V0.S[0]
0x2F806000u, // UMLSL V0.2D, V0.2S, V0.S[0]
0x2F80A000u // UMULL V0.2D, V0.2S, V0.S[0]
0x2F80A000u, // UMULL V0.2D, V0.2S, V0.S[0]
};
}
#endregion
#endregion
[Test, Pairwise]
public void Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H([ValueSource(nameof(_Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_4H_))] ulong z,
@@ -134,7 +138,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S([ValueSource(nameof(_SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_4H_))] ulong z,
@@ -162,7 +166,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D([ValueSource(nameof(_SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_2S_))] ulong z,
@@ -188,4 +192,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdRegElemF
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static IEnumerable<ulong> _1S_F_()
{
yield return 0x00000000FF7FFFFFul; // -Max Normal (float.MinValue)
@@ -23,19 +23,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x00000000007FFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x0000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0x00000000FF800000ul; // -Infinity
yield return 0x000000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0x00000000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0x00000000FFBFFFFFul; // -SNaN (all ones payload)
@@ -65,19 +65,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x007FFFFF007FFFFFul; // +Max Subnormal
yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFF800000FF800000ul; // -Infinity
yield return 0x7F8000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload)
@@ -106,19 +106,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@@ -135,15 +135,15 @@ namespace Ryujinx.Tests.Cpu
yield return rnd2;
}
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _F_Mla_Mls_Se_S_()
{
return new[]
{
0x5F821020u, // FMLA S0, S1, V2.S[0]
0x5F825020u // FMLS S0, S1, V2.S[0]
0x5F825020u, // FMLS S0, S1, V2.S[0]
};
}
@@ -152,7 +152,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x5FC21020u, // FMLA D0, D1, V2.D[0]
0x5FC25020u // FMLS D0, D1, V2.D[0]
0x5FC25020u, // FMLS D0, D1, V2.D[0]
};
}
@@ -161,7 +161,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F801000u, // FMLA V0.2S, V0.2S, V0.S[0]
0x0F805000u // FMLS V0.2S, V0.2S, V0.S[0]
0x0F805000u, // FMLS V0.2S, V0.2S, V0.S[0]
};
}
@@ -170,7 +170,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x4FC01000u, // FMLA V0.2D, V0.2D, V0.D[0]
0x4FC05000u // FMLS V0.2D, V0.2D, V0.D[0]
0x4FC05000u, // FMLS V0.2D, V0.2D, V0.D[0]
};
}
@@ -179,7 +179,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x5F829020u, // FMUL S0, S1, V2.S[0]
0x7F829020u // FMULX S0, S1, V2.S[0]
0x7F829020u, // FMULX S0, S1, V2.S[0]
};
}
@@ -188,7 +188,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x5FC29020u, // FMUL D0, D1, V2.D[0]
0x7FC29020u // FMULX D0, D1, V2.D[0]
0x7FC29020u, // FMULX D0, D1, V2.D[0]
};
}
@@ -197,7 +197,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F809000u, // FMUL V0.2S, V0.2S, V0.S[0]
0x2F809000u // FMULX V0.2S, V0.2S, V0.S[0]
0x2F809000u, // FMULX V0.2S, V0.2S, V0.S[0]
};
}
@@ -206,18 +206,20 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x4FC09000u, // FMUL V0.2D, V0.2D, V0.D[0]
0x6FC09000u // FMULX V0.2D, V0.2D, V0.D[0]
0x6FC09000u, // FMULX V0.2D, V0.2D, V0.D[0]
};
}
#endregion
#endregion
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise] [Explicit] // Fused.
// Fused.
[Test, Pairwise]
[Explicit]
public void F_Mla_Mls_Se_S([ValueSource(nameof(_F_Mla_Mls_Se_S_))] uint opcodes,
[ValueSource(nameof(_1S_F_))] ulong z,
[ValueSource(nameof(_1S_F_))] ulong a,
@@ -243,7 +245,9 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsS);
}
[Test, Pairwise] [Explicit] // Fused.
// Fused.
[Test, Pairwise]
[Explicit]
public void F_Mla_Mls_Se_D([ValueSource(nameof(_F_Mla_Mls_Se_D_))] uint opcodes,
[ValueSource(nameof(_1D_F_))] ulong z,
[ValueSource(nameof(_1D_F_))] ulong a,
@@ -268,9 +272,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsD);
}
[Test, Pairwise] [Explicit] // Fused.
// Fused.
[Test, Pairwise]
[Explicit]
public void F_Mla_Mls_Ve_2S_4S([ValueSource(nameof(_F_Mla_Mls_Ve_2S_4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_2S_F_))] ulong z,
@@ -300,9 +306,11 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsS);
}
[Test, Pairwise] [Explicit] // Fused.
// Fused.
[Test, Pairwise]
[Explicit]
public void F_Mla_Mls_Ve_2D([ValueSource(nameof(_F_Mla_Mls_Ve_2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_1D_F_))] ulong z,
@@ -329,7 +337,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(Fpsr.Ioc | Fpsr.Idc, FpSkips.IfUnderflow, FpTolerances.UpToOneUlpsD);
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mul_Mulx_Se_S([ValueSource(nameof(_F_Mul_Mulx_Se_S_))] uint opcodes,
[ValueSource(nameof(_1S_F_))] ulong a,
[ValueSource(nameof(_2S_F_))] ulong b,
@@ -355,7 +364,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc | Fpsr.Idc);
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mul_Mulx_Se_D([ValueSource(nameof(_F_Mul_Mulx_Se_D_))] uint opcodes,
[ValueSource(nameof(_1D_F_))] ulong a,
[ValueSource(nameof(_1D_F_))] ulong b,
@@ -380,9 +390,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc | Fpsr.Idc);
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mul_Mulx_Ve_2S_4S([ValueSource(nameof(_F_Mul_Mulx_Ve_2S_4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_2S_F_))] ulong z,
@@ -412,9 +423,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(fpsrMask: Fpsr.Ioc | Fpsr.Idc);
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Mul_Mulx_Ve_2D([ValueSource(nameof(_F_Mul_Mulx_Ve_2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm,
[ValueSource(nameof(_1D_F_))] ulong z,

View File

@@ -12,41 +12,53 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdShImm
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _1D_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _1H_()
{
return new[] { 0x0000000000000000ul, 0x0000000000007FFFul,
0x0000000000008000ul, 0x000000000000FFFFul };
return new[] {
0x0000000000000000ul, 0x0000000000007FFFul,
0x0000000000008000ul, 0x000000000000FFFFul,
};
}
private static ulong[] _1S_()
{
return new[] { 0x0000000000000000ul, 0x000000007FFFFFFFul,
0x0000000080000000ul, 0x00000000FFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x000000007FFFFFFFul,
0x0000000080000000ul, 0x00000000FFFFFFFFul,
};
}
private static ulong[] _2S_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _4H_()
{
return new[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _8B_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static IEnumerable<ulong> _2S_F_W_()
@@ -73,19 +85,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x007FFFFF007FFFFFul; // +Max Subnormal
yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFF800000FF800000ul; // -Infinity
yield return 0x7F8000007F800000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload)
@@ -133,19 +145,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros)
if (!_noZeros)
{
yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero
}
if (!NoInfs)
if (!_noInfs)
{
yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity
}
if (!NoNaNs)
if (!_noNaNs)
{
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@@ -170,15 +182,15 @@ namespace Ryujinx.Tests.Cpu
yield return rnd4;
}
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _F_Cvt_Z_SU_V_Fixed_2S_4S_()
{
return new[]
{
0x0F20FC00u, // FCVTZS V0.2S, V0.2S, #32
0x2F20FC00u // FCVTZU V0.2S, V0.2S, #32
0x2F20FC00u, // FCVTZU V0.2S, V0.2S, #32
};
}
@@ -187,7 +199,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x4F40FC00u, // FCVTZS V0.2D, V0.2D, #64
0x6F40FC00u // FCVTZU V0.2D, V0.2D, #64
0x6F40FC00u, // FCVTZU V0.2D, V0.2D, #64
};
}
@@ -196,7 +208,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x5F20E420u, // SCVTF S0, S1, #32
0x7F20E420u // UCVTF S0, S1, #32
0x7F20E420u, // UCVTF S0, S1, #32
};
}
@@ -205,7 +217,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x5F40E420u, // SCVTF D0, D1, #64
0x7F40E420u // UCVTF D0, D1, #64
0x7F40E420u, // UCVTF D0, D1, #64
};
}
@@ -214,7 +226,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F20E400u, // SCVTF V0.2S, V0.2S, #32
0x2F20E400u // UCVTF V0.2S, V0.2S, #32
0x2F20E400u, // UCVTF V0.2S, V0.2S, #32
};
}
@@ -223,7 +235,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x4F40E400u, // SCVTF V0.2D, V0.2D, #64
0x6F40E400u // UCVTF V0.2D, V0.2D, #64
0x6F40E400u, // UCVTF V0.2D, V0.2D, #64
};
}
@@ -232,7 +244,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x5F405400u, // SHL D0, D0, #0
0x7F405400u // SLI D0, D0, #0
0x7F405400u, // SLI D0, D0, #0
};
}
@@ -241,7 +253,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F085400u, // SHL V0.8B, V0.8B, #0
0x2F085400u // SLI V0.8B, V0.8B, #0
0x2F085400u, // SLI V0.8B, V0.8B, #0
};
}
@@ -250,7 +262,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F105400u, // SHL V0.4H, V0.4H, #0
0x2F105400u // SLI V0.4H, V0.4H, #0
0x2F105400u, // SLI V0.4H, V0.4H, #0
};
}
@@ -259,7 +271,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F205400u, // SHL V0.2S, V0.2S, #0
0x2F205400u // SLI V0.2S, V0.2S, #0
0x2F205400u, // SLI V0.2S, V0.2S, #0
};
}
@@ -268,7 +280,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x4F405400u, // SHL V0.2D, V0.2D, #0
0x6F405400u // SLI V0.2D, V0.2D, #0
0x6F405400u, // SLI V0.2D, V0.2D, #0
};
}
@@ -277,7 +289,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F08A400u, // SSHLL V0.8H, V0.8B, #0
0x2F08A400u // USHLL V0.8H, V0.8B, #0
0x2F08A400u, // USHLL V0.8H, V0.8B, #0
};
}
@@ -286,7 +298,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F10A400u, // SSHLL V0.4S, V0.4H, #0
0x2F10A400u // USHLL V0.4S, V0.4H, #0
0x2F10A400u, // USHLL V0.4S, V0.4H, #0
};
}
@@ -295,7 +307,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F20A400u, // SSHLL V0.2D, V0.2S, #0
0x2F20A400u // USHLL V0.2D, V0.2S, #0
0x2F20A400u, // USHLL V0.2D, V0.2S, #0
};
}
@@ -311,7 +323,7 @@ namespace Ryujinx.Tests.Cpu
0x7F402400u, // URSHR D0, D0, #64
0x7F403400u, // URSRA D0, D0, #64
0x7F400400u, // USHR D0, D0, #64
0x7F401400u // USRA D0, D0, #64
0x7F401400u, // USRA D0, D0, #64
};
}
@@ -327,7 +339,7 @@ namespace Ryujinx.Tests.Cpu
0x2F082400u, // URSHR V0.8B, V0.8B, #8
0x2F083400u, // URSRA V0.8B, V0.8B, #8
0x2F080400u, // USHR V0.8B, V0.8B, #8
0x2F081400u // USRA V0.8B, V0.8B, #8
0x2F081400u, // USRA V0.8B, V0.8B, #8
};
}
@@ -343,7 +355,7 @@ namespace Ryujinx.Tests.Cpu
0x2F102400u, // URSHR V0.4H, V0.4H, #16
0x2F103400u, // URSRA V0.4H, V0.4H, #16
0x2F100400u, // USHR V0.4H, V0.4H, #16
0x2F101400u // USRA V0.4H, V0.4H, #16
0x2F101400u, // USRA V0.4H, V0.4H, #16
};
}
@@ -359,7 +371,7 @@ namespace Ryujinx.Tests.Cpu
0x2F202400u, // URSHR V0.2S, V0.2S, #32
0x2F203400u, // URSRA V0.2S, V0.2S, #32
0x2F200400u, // USHR V0.2S, V0.2S, #32
0x2F201400u // USRA V0.2S, V0.2S, #32
0x2F201400u, // USRA V0.2S, V0.2S, #32
};
}
@@ -375,7 +387,7 @@ namespace Ryujinx.Tests.Cpu
0x6F402400u, // URSHR V0.2D, V0.2D, #64
0x6F403400u, // URSRA V0.2D, V0.2D, #64
0x6F400400u, // USHR V0.2D, V0.2D, #64
0x6F401400u // USRA V0.2D, V0.2D, #64
0x6F401400u, // USRA V0.2D, V0.2D, #64
};
}
@@ -384,7 +396,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F088C00u, // RSHRN V0.8B, V0.8H, #8
0x0F088400u // SHRN V0.8B, V0.8H, #8
0x0F088400u, // SHRN V0.8B, V0.8H, #8
};
}
@@ -393,7 +405,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F108C00u, // RSHRN V0.4H, V0.4S, #16
0x0F108400u // SHRN V0.4H, V0.4S, #16
0x0F108400u, // SHRN V0.4H, V0.4S, #16
};
}
@@ -402,7 +414,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0F208C00u, // RSHRN V0.2S, V0.2D, #32
0x0F208400u // SHRN V0.2S, V0.2D, #32
0x0F208400u, // SHRN V0.2S, V0.2D, #32
};
}
@@ -415,7 +427,7 @@ namespace Ryujinx.Tests.Cpu
0x7F088C00u, // SQRSHRUN B0, H0, #8
0x5F089400u, // SQSHRN B0, H0, #8
0x7F089400u, // UQSHRN B0, H0, #8
0x7F088400u // SQSHRUN B0, H0, #8
0x7F088400u, // SQSHRUN B0, H0, #8
};
}
@@ -428,7 +440,7 @@ namespace Ryujinx.Tests.Cpu
0x7F108C00u, // SQRSHRUN H0, S0, #16
0x5F109400u, // SQSHRN H0, S0, #16
0x7F109400u, // UQSHRN H0, S0, #16
0x7F108400u // SQSHRUN H0, S0, #16
0x7F108400u, // SQSHRUN H0, S0, #16
};
}
@@ -441,7 +453,7 @@ namespace Ryujinx.Tests.Cpu
0x7F208C00u, // SQRSHRUN S0, D0, #32
0x5F209400u, // SQSHRN S0, D0, #32
0x7F209400u, // UQSHRN S0, D0, #32
0x7F208400u // SQSHRUN S0, D0, #32
0x7F208400u, // SQSHRUN S0, D0, #32
};
}
@@ -454,7 +466,7 @@ namespace Ryujinx.Tests.Cpu
0x2F088C00u, // SQRSHRUN V0.8B, V0.8H, #8
0x0F089400u, // SQSHRN V0.8B, V0.8H, #8
0x2F089400u, // UQSHRN V0.8B, V0.8H, #8
0x2F088400u // SQSHRUN V0.8B, V0.8H, #8
0x2F088400u, // SQSHRUN V0.8B, V0.8H, #8
};
}
@@ -467,7 +479,7 @@ namespace Ryujinx.Tests.Cpu
0x2F108C00u, // SQRSHRUN V0.4H, V0.4S, #16
0x0F109400u, // SQSHRN V0.4H, V0.4S, #16
0x2F109400u, // UQSHRN V0.4H, V0.4S, #16
0x2F108400u // SQSHRUN V0.4H, V0.4S, #16
0x2F108400u, // SQSHRUN V0.4H, V0.4S, #16
};
}
@@ -480,20 +492,21 @@ namespace Ryujinx.Tests.Cpu
0x2F208C00u, // SQRSHRUN V0.2S, V0.2D, #32
0x0F209400u, // SQSHRN V0.2S, V0.2D, #32
0x2F209400u, // UQSHRN V0.2S, V0.2D, #32
0x2F208400u // SQSHRUN V0.2S, V0.2D, #32
0x2F208400u, // SQSHRUN V0.2S, V0.2D, #32
};
}
#endregion
#endregion
private const int RndCnt = 2;
private const int RndCnt = 2;
private static readonly bool NoZeros = false;
private static readonly bool NoInfs = false;
private static readonly bool NoNaNs = false;
private static readonly bool _noZeros = false;
private static readonly bool _noInfs = false;
private static readonly bool _noNaNs = false;
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_Z_SU_V_Fixed_2S_4S([ValueSource(nameof(_F_Cvt_Z_SU_V_Fixed_2S_4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_F_W_))] ulong z,
[ValueSource(nameof(_2S_F_W_))] ulong a,
@@ -514,9 +527,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void F_Cvt_Z_SU_V_Fixed_2D([ValueSource(nameof(_F_Cvt_Z_SU_V_Fixed_2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_F_X_))] ulong z,
[ValueSource(nameof(_1D_F_X_))] ulong a,
@@ -535,7 +549,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_S_Fixed_S([ValueSource(nameof(_SU_Cvt_F_S_Fixed_S_))] uint opcodes,
[ValueSource(nameof(_1S_))] ulong a,
[Values(1u, 32u)] uint fBits)
@@ -553,7 +568,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_S_Fixed_D([ValueSource(nameof(_SU_Cvt_F_S_Fixed_D_))] uint opcodes,
[ValueSource(nameof(_1D_))] ulong a,
[Values(1u, 64u)] uint fBits)
@@ -571,9 +587,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_V_Fixed_2S_4S([ValueSource(nameof(_SU_Cvt_F_V_Fixed_2S_4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -594,9 +611,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise] [Explicit]
[Test, Pairwise]
[Explicit]
public void SU_Cvt_F_V_Fixed_2D([ValueSource(nameof(_SU_Cvt_F_V_Fixed_2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -617,7 +635,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Shl_Sli_S_D([ValueSource(nameof(_Shl_Sli_S_D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -638,7 +656,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Shl_Sli_V_8B_16B([ValueSource(nameof(_Shl_Sli_V_8B_16B_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a,
@@ -661,7 +679,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Shl_Sli_V_4H_8H([ValueSource(nameof(_Shl_Sli_V_4H_8H_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
@@ -684,7 +702,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Shl_Sli_V_2S_4S([ValueSource(nameof(_Shl_Sli_V_2S_4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -707,7 +725,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Shl_Sli_V_2D([ValueSource(nameof(_Shl_Sli_V_2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -728,7 +746,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void SU_Shll_V_8B8H_16B8H([ValueSource(nameof(_SU_Shll_V_8B8H_16B8H_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a,
@@ -751,7 +769,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void SU_Shll_V_4H4S_8H4S([ValueSource(nameof(_SU_Shll_V_4H4S_8H4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
@@ -774,7 +792,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void SU_Shll_V_2S2D_4S2D([ValueSource(nameof(_SU_Shll_V_2S2D_4S2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -797,7 +815,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImm_Sri_S_D([ValueSource(nameof(_ShrImm_Sri_S_D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -818,7 +836,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImm_Sri_V_8B_16B([ValueSource(nameof(_ShrImm_Sri_V_8B_16B_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a,
@@ -841,7 +859,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImm_Sri_V_4H_8H([ValueSource(nameof(_ShrImm_Sri_V_4H_8H_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
@@ -864,7 +882,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImm_Sri_V_2S_4S([ValueSource(nameof(_ShrImm_Sri_V_2S_4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -887,7 +905,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImm_Sri_V_2D([ValueSource(nameof(_ShrImm_Sri_V_2D_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -908,7 +926,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmNarrow_V_8H8B_8H16B([ValueSource(nameof(_ShrImmNarrow_V_8H8B_8H16B_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
@@ -931,7 +949,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmNarrow_V_4S4H_4S8H([ValueSource(nameof(_ShrImmNarrow_V_4S4H_4S8H_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -954,7 +972,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmNarrow_V_2D2S_2D4S([ValueSource(nameof(_ShrImmNarrow_V_2D2S_2D4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -977,7 +995,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmSaturatingNarrow_S_HB([ValueSource(nameof(_ShrImmSaturatingNarrow_S_HB_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1H_))] ulong z,
[ValueSource(nameof(_1H_))] ulong a,
@@ -998,7 +1016,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmSaturatingNarrow_S_SH([ValueSource(nameof(_ShrImmSaturatingNarrow_S_SH_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1S_))] ulong z,
[ValueSource(nameof(_1S_))] ulong a,
@@ -1019,7 +1037,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmSaturatingNarrow_S_DS([ValueSource(nameof(_ShrImmSaturatingNarrow_S_DS_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -1040,7 +1058,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmSaturatingNarrow_V_8H8B_8H16B([ValueSource(nameof(_ShrImmSaturatingNarrow_V_8H8B_8H16B_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a,
@@ -1063,7 +1081,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmSaturatingNarrow_V_4S4H_4S8H([ValueSource(nameof(_ShrImmSaturatingNarrow_V_4S4H_4S8H_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a,
@@ -1086,7 +1104,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void ShrImmSaturatingNarrow_V_2D2S_2D4S([ValueSource(nameof(_ShrImmSaturatingNarrow_V_2D2S_2D4S_))] uint opcodes,
[Values(0u)] uint rd,
[Values(0u)] uint rd,
[Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a,
@@ -1108,4 +1126,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -10,30 +10,41 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdShImm32
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _1D_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _2S_()
{
return new[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul, 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul };
return new[]
{
0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul, 0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _4H_()
{
return new[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul, 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul };
return new[]
{
0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul, 0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static ulong[] _8B_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful, 0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
return new[]
{
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful, 0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul,
};
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _Vshr_Imm_SU8_()
{
return new[]
@@ -41,7 +52,7 @@ namespace Ryujinx.Tests.Cpu
0xf2880010u, // VSHR.S8 D0, D0, #8
0xf2880110u, // VSRA.S8 D0, D0, #8
0xf2880210u, // VRSHR.S8 D0, D0, #8
0xf2880310u // VRSRA.S8 D0, D0, #8
0xf2880310u, // VRSRA.S8 D0, D0, #8
};
}
@@ -52,7 +63,7 @@ namespace Ryujinx.Tests.Cpu
0xf2900010u, // VSHR.S16 D0, D0, #16
0xf2900110u, // VSRA.S16 D0, D0, #16
0xf2900210u, // VRSHR.S16 D0, D0, #16
0xf2900310u // VRSRA.S16 D0, D0, #16
0xf2900310u, // VRSRA.S16 D0, D0, #16
};
}
@@ -63,7 +74,7 @@ namespace Ryujinx.Tests.Cpu
0xf2a00010u, // VSHR.S32 D0, D0, #32
0xf2a00110u, // VSRA.S32 D0, D0, #32
0xf2a00210u, // VRSHR.S32 D0, D0, #32
0xf2a00310u // VRSRA.S32 D0, D0, #32
0xf2a00310u, // VRSRA.S32 D0, D0, #32
};
}
@@ -73,7 +84,7 @@ namespace Ryujinx.Tests.Cpu
{
0xf2800190u, // VSRA.S64 D0, D0, #64
0xf2800290u, // VRSHR.S64 D0, D0, #64
0xf2800090u // VSHR.S64 D0, D0, #64
0xf2800090u, // VSHR.S64 D0, D0, #64
};
}
@@ -83,7 +94,7 @@ namespace Ryujinx.Tests.Cpu
{
0xf2800910u, // VORR.I16 D0, #0 (immediate value changes it into QSHRN)
0xf2800950u, // VORR.I16 Q0, #0 (immediate value changes it into QRSHRN)
0xf2800850u // VMOV.I16 Q0, #0 (immediate value changes it into RSHRN)
0xf2800850u, // VMOV.I16 Q0, #0 (immediate value changes it into RSHRN)
};
}
@@ -92,10 +103,10 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0xf3800810u, // VMOV.I16 D0, #0x80 (immediate value changes it into QSHRUN)
0xf3800850u // VMOV.I16 Q0, #0x80 (immediate value changes it into QRSHRUN)
0xf3800850u, // VMOV.I16 Q0, #0x80 (immediate value changes it into QRSHRUN)
};
}
#endregion
#endregion
private const int RndCnt = 2;
private const int RndCntShiftImm = 2;
@@ -171,12 +182,14 @@ namespace Ryujinx.Tests.Cpu
{
opcode |= 1 << 6;
rd >>= 1; rd <<= 1;
rm >>= 1; rm <<= 1;
rd >>= 1;
rd <<= 1;
rm >>= 1;
rm <<= 1;
}
opcode |= ((rd & 0xf) << 12) | ((rd & 0x10) << 18);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= ((rm & 0xf) << 0) | ((rm & 0x10) << 1);
opcode |= (imm6 & 0x3f) << 16;
@@ -312,4 +325,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

View File

@@ -11,19 +11,19 @@ namespace Ryujinx.Tests.Cpu
{
#if SimdTbl
#region "Helper methods"
#region "Helper methods"
private static ulong GenIdxsForTbls(int regs)
{
const byte IdxInRngMin = 0;
byte idxInRngMax = (byte)((16 * regs) - 1);
byte idxOutRngMin = (byte) (16 * regs);
byte idxInRngMax = (byte)((16 * regs) - 1);
byte idxOutRngMin = (byte)(16 * regs);
const byte IdxOutRngMax = 255;
ulong idxs = 0ul;
for (int cnt = 1; cnt <= 8; cnt++)
{
ulong idxInRng = TestContext.CurrentContext.Random.NextByte(IdxInRngMin, idxInRngMax);
ulong idxInRng = TestContext.CurrentContext.Random.NextByte(IdxInRngMin, idxInRngMax);
ulong idxOutRng = TestContext.CurrentContext.Random.NextByte(idxOutRngMin, IdxOutRngMax);
ulong idx = TestContext.CurrentContext.Random.NextBool() ? idxInRng : idxOutRng;
@@ -33,13 +33,15 @@ namespace Ryujinx.Tests.Cpu
return idxs;
}
#endregion
#endregion
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static ulong[] _8B_()
{
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul };
return new[] {
0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul,
};
}
private static IEnumerable<ulong> _GenIdxsForTbl1_()
@@ -93,15 +95,15 @@ namespace Ryujinx.Tests.Cpu
yield return GenIdxsForTbls(regs: 4);
}
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _SingleRegisterTable_V_8B_16B_()
{
return new[]
{
0x0E000000u, // TBL V0.8B, { V0.16B }, V0.8B
0x0E001000u // TBX V0.8B, { V0.16B }, V0.8B
0x0E001000u, // TBX V0.8B, { V0.16B }, V0.8B
};
}
@@ -110,7 +112,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0E002000u, // TBL V0.8B, { V0.16B, V1.16B }, V0.8B
0x0E003000u // TBX V0.8B, { V0.16B, V1.16B }, V0.8B
0x0E003000u, // TBX V0.8B, { V0.16B, V1.16B }, V0.8B
};
}
@@ -119,7 +121,7 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0E004000u, // TBL V0.8B, { V0.16B, V1.16B, V2.16B }, V0.8B
0x0E005000u // TBX V0.8B, { V0.16B, V1.16B, V2.16B }, V0.8B
0x0E005000u, // TBX V0.8B, { V0.16B, V1.16B, V2.16B }, V0.8B
};
}
@@ -128,10 +130,10 @@ namespace Ryujinx.Tests.Cpu
return new[]
{
0x0E006000u, // TBL V0.8B, { V0.16B, V1.16B, V2.16B, V3.16B }, V0.8B
0x0E006000u // TBX V0.8B, { V0.16B, V1.16B, V2.16B, V3.16B }, V0.8B
0x0E006000u, // TBX V0.8B, { V0.16B, V1.16B, V2.16B, V3.16B }, V0.8B
};
}
#endregion
#endregion
private const int RndCntIdxs = 2;
@@ -184,7 +186,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Mod_TwoRegisterTable_V_8B_16B([ValueSource(nameof(_TwoRegisterTable_V_8B_16B_))] uint opcodes,
[Values(30u, 1u)] uint rd,
[Values(31u)] uint rn,
[Values(31u)] uint rn,
[Values(1u, 30u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong table0,
@@ -197,8 +199,8 @@ namespace Ryujinx.Tests.Cpu
V128 v30 = MakeVectorE0E1(z, z);
V128 v31 = MakeVectorE0E1(table0, table0);
V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(indexes, indexes);
V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(indexes, indexes);
SingleOpcode(opcodes, v0: v0, v1: v1, v30: v30, v31: v31);
@@ -234,7 +236,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Mod_ThreeRegisterTable_V_8B_16B([ValueSource(nameof(_ThreeRegisterTable_V_8B_16B_))] uint opcodes,
[Values(30u, 2u)] uint rd,
[Values(31u)] uint rn,
[Values(31u)] uint rn,
[Values(2u, 30u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong table0,
@@ -248,9 +250,9 @@ namespace Ryujinx.Tests.Cpu
V128 v30 = MakeVectorE0E1(z, z);
V128 v31 = MakeVectorE0E1(table0, table0);
V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(table2, table2);
V128 v2 = MakeVectorE0E1(indexes, indexes);
V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(table2, table2);
V128 v2 = MakeVectorE0E1(indexes, indexes);
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v30: v30, v31: v31);
@@ -288,7 +290,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise]
public void Mod_FourRegisterTable_V_8B_16B([ValueSource(nameof(_FourRegisterTable_V_8B_16B_))] uint opcodes,
[Values(30u, 3u)] uint rd,
[Values(31u)] uint rn,
[Values(31u)] uint rn,
[Values(3u, 30u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong table0,
@@ -303,10 +305,10 @@ namespace Ryujinx.Tests.Cpu
V128 v30 = MakeVectorE0E1(z, z);
V128 v31 = MakeVectorE0E1(table0, table0);
V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(table2, table2);
V128 v2 = MakeVectorE0E1(table3, table3);
V128 v3 = MakeVectorE0E1(indexes, indexes);
V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(table2, table2);
V128 v2 = MakeVectorE0E1(table3, table3);
V128 v3 = MakeVectorE0E1(indexes, indexes);
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v3: v3, v30: v30, v31: v31);

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Tests.Cpu
{
#if System
#region "ValueSource (Types)"
#region "ValueSource (Types)"
private static IEnumerable<ulong> _GenNzcv_()
{
yield return 0x0000000000000000ul;
@@ -33,23 +33,23 @@ namespace Ryujinx.Tests.Cpu
yield return rnd;
}
#endregion
#endregion
#region "ValueSource (Opcodes)"
#region "ValueSource (Opcodes)"
private static uint[] _MrsMsr_Nzcv_()
{
return new[]
{
0xD53B4200u, // MRS X0, NZCV
0xD51B4200u // MSR NZCV, X0
0xD51B4200u, // MSR NZCV, X0
};
}
#endregion
#endregion
[Test, Pairwise]
public void MrsMsr_Nzcv([ValueSource("_MrsMsr_Nzcv_")] uint opcodes,
public void MrsMsr_Nzcv([ValueSource(nameof(_MrsMsr_Nzcv_))] uint opcodes,
[Values(0u, 1u, 31u)] uint rt,
[ValueSource("_GenNzcv_")] ulong xt)
[ValueSource(nameof(_GenNzcv_))] ulong xt)
{
opcodes |= (rt & 31) << 0;
@@ -66,4 +66,4 @@ namespace Ryujinx.Tests.Cpu
}
#endif
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -164,4 +164,4 @@ namespace Ryujinx.Tests.Cpu
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
}
}
}
}

View File

@@ -1,4 +1,5 @@
using NUnit.Framework;
using System;
namespace Ryujinx.Tests.Cpu
{
@@ -14,70 +15,70 @@ namespace Ryujinx.Tests.Cpu
public static readonly PrecomputedMemoryThumbTestCase[] ImmTestCases =
{
// STRB (imm8)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf80c, 0x1b2f, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000023bd, 0x000027bb, 0x00002715, 0x000028f5, 0x0000233f, 0x0000213b, 0x00002eea, 0x0000282b, 0x000021e1, 0x0000264c, 0x000029e0, 0x00002ae7, 0x000021ff, 0x000026e3, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0x000023bd, 0x000027bb, 0x00002715, 0x000028f5, 0x0000233f, 0x0000213b, 0x00002eea, 0x0000282b, 0x000021e1, 0x0000264c, 0x000029e0, 0x00002ae7, 0x0000222e, 0x000026e3, 0x00000001, 0x800001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x21fe, Value: 0xbbfe) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf80a, 0x2f81, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000223c, 0x00002db9, 0x00002900, 0x0000247c, 0x00002b0a, 0x0000266b, 0x000026df, 0x00002447, 0x000024bb, 0x00002687, 0x0000266f, 0x00002a80, 0x000025ff, 0x00002881, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0x0000223c, 0x00002db9, 0x00002900, 0x0000247c, 0x00002b0a, 0x0000266b, 0x000026df, 0x00002447, 0x000024bb, 0x00002687, 0x000026f0, 0x00002a80, 0x000025ff, 0x00002881, 0x00000001, 0xa00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x26f0, Value: 0x2600) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf803, 0x6968, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000026ed, 0x00002685, 0x00002cd1, 0x00002dac, 0x00002a23, 0x00002626, 0x00002ec9, 0x0000245c, 0x000024ef, 0x00002319, 0x000026ce, 0x0000214d, 0x00002401, 0x000028b4, 0x00000001, 0x300001f0 },
FinalRegs = new uint[] { 0x000026ed, 0x00002685, 0x00002cd1, 0x00002d44, 0x00002a23, 0x00002626, 0x00002ec9, 0x0000245c, 0x000024ef, 0x00002319, 0x000026ce, 0x0000214d, 0x00002401, 0x000028b4, 0x00000001, 0x300001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2dac, Value: 0x2dc9) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf804, 0x89ad, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000265d, 0x00002b9c, 0x00002360, 0x000029ec, 0x00002413, 0x00002d8e, 0x00002aad, 0x00002d29, 0x00002bca, 0x00002a44, 0x00002980, 0x00002710, 0x000022fa, 0x0000222e, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x0000265d, 0x00002b9c, 0x00002360, 0x000029ec, 0x00002366, 0x00002d8e, 0x00002aad, 0x00002d29, 0x00002bca, 0x00002a44, 0x00002980, 0x00002710, 0x000022fa, 0x0000222e, 0x00000001, 0xc00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2412, Value: 0xca12) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf80d, 0xa9fe, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000298d, 0x00002e6c, 0x00002986, 0x00002ebb, 0x0000213e, 0x00002e39, 0x0000246f, 0x00002b6c, 0x00002ee2, 0x0000259e, 0x0000250a, 0x000029f6, 0x000021e7, 0x00002d9d, 0x00000001, 0x900001f0 },
FinalRegs = new uint[] { 0x0000298d, 0x00002e6c, 0x00002986, 0x00002ebb, 0x0000213e, 0x00002e39, 0x0000246f, 0x00002b6c, 0x00002ee2, 0x0000259e, 0x0000250a, 0x000029f6, 0x000021e7, 0x00002c9f, 0x00000001, 0x900001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2d9c, Value: 0x0a9c) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf80d, 0x3c46, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002c6f, 0x000028cc, 0x000025f0, 0x000022cc, 0x00002de3, 0x0000243c, 0x000025fb, 0x00002e88, 0x00002985, 0x000023ee, 0x00002120, 0x00002d50, 0x0000270a, 0x00002bbd, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0x00002c6f, 0x000028cc, 0x000025f0, 0x000022cc, 0x00002de3, 0x0000243c, 0x000025fb, 0x00002e88, 0x00002985, 0x000023ee, 0x00002120, 0x00002d50, 0x0000270a, 0x00002bbd, 0x00000001, 0xa00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2b76, Value: 0xcc76) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf801, 0x6c56, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002d6e, 0x00002530, 0x00002e6d, 0x00002942, 0x00002985, 0x00002d64, 0x00002a73, 0x00002ac6, 0x00002955, 0x00002881, 0x0000221d, 0x00002cb0, 0x0000225f, 0x00002534, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0x00002d6e, 0x00002530, 0x00002e6d, 0x00002942, 0x00002985, 0x00002d64, 0x00002a73, 0x00002ac6, 0x00002955, 0x00002881, 0x0000221d, 0x00002cb0, 0x0000225f, 0x00002534, 0x00000001, 0x100001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x24da, Value: 0x2473) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf809, 0xcc76, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002d50, 0x000025f2, 0x0000250a, 0x0000214c, 0x000023d1, 0x00002115, 0x00002c27, 0x00002540, 0x0000222b, 0x00002d03, 0x00002679, 0x00002b52, 0x00002eee, 0x00002b2a, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x00002d50, 0x000025f2, 0x0000250a, 0x0000214c, 0x000023d1, 0x00002115, 0x00002c27, 0x00002540, 0x0000222b, 0x00002d03, 0x00002679, 0x00002b52, 0x00002eee, 0x00002b2a, 0x00000001, 0xd00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2c8c, Value: 0xee8c) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf808, 0x1c8d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002844, 0x00002b78, 0x000028b0, 0x000026ff, 0x0000280b, 0x00002e0b, 0x00002de4, 0x00002b53, 0x00002ecd, 0x000021b5, 0x000026bc, 0x00002e9d, 0x00002d33, 0x000027f0, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0x00002844, 0x00002b78, 0x000028b0, 0x000026ff, 0x0000280b, 0x00002e0b, 0x00002de4, 0x00002b53, 0x00002ecd, 0x000021b5, 0x000026bc, 0x00002e9d, 0x00002d33, 0x000027f0, 0x00000001, 0x800001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2e40, Value: 0x2e78) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf80b, 0xbc26, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002244, 0x000025ad, 0x00002434, 0x00002b06, 0x00002ebd, 0x0000292b, 0x00002431, 0x00002e12, 0x0000289b, 0x0000265a, 0x00002747, 0x00002bac, 0x00002dae, 0x00002582, 0x00000001, 0xf00001f0 },
@@ -85,35 +86,35 @@ namespace Ryujinx.Tests.Cpu
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2b86, Value: 0x2bac) },
},
// STRB (imm12)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf887, 0x67c2, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x700001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x27c2, Value: 0x2700) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf883, 0x9fda, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xc00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2fda, Value: 0x2f00) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf889, 0xd200, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x400001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf88c, 0x1c5b, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x500001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2c5a, Value: 0x005a) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf887, 0x9fe2, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xe00001f0 },
@@ -121,70 +122,70 @@ namespace Ryujinx.Tests.Cpu
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2fe2, Value: 0x2f00) },
},
// STRH (imm8)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf826, 0x0b0a, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000025a2, 0x000024d5, 0x00002ca1, 0x0000238a, 0x0000279c, 0x0000244c, 0x00002620, 0x00002c0e, 0x0000233e, 0x0000285f, 0x000021ab, 0x00002bd0, 0x0000281f, 0x00002be7, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x000025a2, 0x000024d5, 0x00002ca1, 0x0000238a, 0x0000279c, 0x0000244c, 0x0000262a, 0x00002c0e, 0x0000233e, 0x0000285f, 0x000021ab, 0x00002bd0, 0x0000281f, 0x00002be7, 0x00000001, 0x600001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2620, Value: 0x25a2) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf827, 0xcf61, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002555, 0x0000238f, 0x00002829, 0x000028c8, 0x00002399, 0x00002aab, 0x00002d6f, 0x000029eb, 0x000029e0, 0x00002d33, 0x0000292a, 0x00002b33, 0x00002e29, 0x00002ca4, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0x00002555, 0x0000238f, 0x00002829, 0x000028c8, 0x00002399, 0x00002aab, 0x00002d6f, 0x00002a4c, 0x000029e0, 0x00002d33, 0x0000292a, 0x00002b33, 0x00002e29, 0x00002ca4, 0x00000001, 0x100001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2a4c, Value: 0x2e29) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf821, 0x9b00, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000027ba, 0x00002514, 0x00002b07, 0x00002daf, 0x00002790, 0x0000274b, 0x00002379, 0x00002a98, 0x000024c8, 0x00002398, 0x000021ba, 0x00002959, 0x00002821, 0x00002d09, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x000027ba, 0x00002514, 0x00002b07, 0x00002daf, 0x00002790, 0x0000274b, 0x00002379, 0x00002a98, 0x000024c8, 0x00002398, 0x000021ba, 0x00002959, 0x00002821, 0x00002d09, 0x00000001, 0x500001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2514, Value: 0x2398) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf82c, 0xa927, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000226a, 0x00002792, 0x00002870, 0x00002918, 0x00002757, 0x00002679, 0x00002546, 0x000027f5, 0x00002edc, 0x00002cd3, 0x0000274a, 0x00002562, 0x000029a1, 0x00002976, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0x0000226a, 0x00002792, 0x00002870, 0x00002918, 0x00002757, 0x00002679, 0x00002546, 0x000027f5, 0x00002edc, 0x00002cd3, 0x0000274a, 0x00002562, 0x0000297a, 0x00002976, 0x00000001, 0x100001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x29a0, Value: 0x4aa0), (Address: 0x29a2, Value: 0x2927) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf824, 0xcfe4, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000238b, 0x00002d22, 0x00002476, 0x000028ae, 0x00002442, 0x0000212b, 0x000026de, 0x00002a1a, 0x00002a02, 0x00002e47, 0x00002b2d, 0x00002427, 0x00002d1c, 0x000026d4, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x0000238b, 0x00002d22, 0x00002476, 0x000028ae, 0x00002526, 0x0000212b, 0x000026de, 0x00002a1a, 0x00002a02, 0x00002e47, 0x00002b2d, 0x00002427, 0x00002d1c, 0x000026d4, 0x00000001, 0xd00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2526, Value: 0x2d1c) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf820, 0x1c3d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002227, 0x00002b29, 0x0000232a, 0x0000214e, 0x000029ef, 0x00002522, 0x000029d3, 0x0000286c, 0x000029b2, 0x00002147, 0x00002c65, 0x00002891, 0x000029c2, 0x000028a5, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0x00002227, 0x00002b29, 0x0000232a, 0x0000214e, 0x000029ef, 0x00002522, 0x000029d3, 0x0000286c, 0x000029b2, 0x00002147, 0x00002c65, 0x00002891, 0x000029c2, 0x000028a5, 0x00000001, 0x800001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x21ea, Value: 0x2b29) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf826, 0x1cdf, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002232, 0x000029a1, 0x00002938, 0x00002ae7, 0x000029a4, 0x00002366, 0x0000273a, 0x000023f6, 0x00002601, 0x00002919, 0x000028e3, 0x00002907, 0x000023c1, 0x00002138, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0x00002232, 0x000029a1, 0x00002938, 0x00002ae7, 0x000029a4, 0x00002366, 0x0000273a, 0x000023f6, 0x00002601, 0x00002919, 0x000028e3, 0x00002907, 0x000023c1, 0x00002138, 0x00000001, 0x100001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x265a, Value: 0xa15a), (Address: 0x265c, Value: 0x2629) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf82b, 0x3c66, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002974, 0x00002372, 0x0000276c, 0x000021df, 0x00002272, 0x00002928, 0x00002c50, 0x0000290e, 0x00002319, 0x000021d1, 0x00002a82, 0x000027ff, 0x00002730, 0x000027b2, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0x00002974, 0x00002372, 0x0000276c, 0x000021df, 0x00002272, 0x00002928, 0x00002c50, 0x0000290e, 0x00002319, 0x000021d1, 0x00002a82, 0x000027ff, 0x00002730, 0x000027b2, 0x00000001, 0x700001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2798, Value: 0xdf98), (Address: 0x279a, Value: 0x2721) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf822, 0x3c06, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000021b8, 0x00002357, 0x00002b00, 0x00002207, 0x00002648, 0x0000219c, 0x000021d2, 0x000023b0, 0x00002368, 0x00002a41, 0x000026ac, 0x00002a86, 0x00002879, 0x00002c1d, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0x000021b8, 0x00002357, 0x00002b00, 0x00002207, 0x00002648, 0x0000219c, 0x000021d2, 0x000023b0, 0x00002368, 0x00002a41, 0x000026ac, 0x00002a86, 0x00002879, 0x00002c1d, 0x00000001, 0x700001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2afa, Value: 0x2207) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf824, 0xac84, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002796, 0x000027c8, 0x0000241b, 0x0000214d, 0x0000220b, 0x00002587, 0x00002130, 0x00002910, 0x00002ac2, 0x00002e74, 0x000028f8, 0x000024bf, 0x0000263a, 0x00002625, 0x00000001, 0x600001f0 },
@@ -192,35 +193,35 @@ namespace Ryujinx.Tests.Cpu
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2186, Value: 0xf886), (Address: 0x2188, Value: 0x2128) },
},
// STRH (imm12)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8a5, 0x59d4, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x000001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x29d4, Value: 0x2000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8ac, 0xc533, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xe00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2532, Value: 0x0032), (Address: 0x2534, Value: 0x2520) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8a3, 0xb559, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x000001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2558, Value: 0x0058), (Address: 0x255a, Value: 0x2520) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8a5, 0xdb3a, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xb00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2b3a, Value: 0x2000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8a9, 0x02cc, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xc00001f0 },
@@ -228,70 +229,70 @@ namespace Ryujinx.Tests.Cpu
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x22cc, Value: 0x2000) },
},
// STR (imm8)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf846, 0x1fb4, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002b17, 0x0000272f, 0x00002483, 0x0000284c, 0x0000287f, 0x0000238f, 0x0000222d, 0x00002259, 0x0000249d, 0x00002e3f, 0x00002323, 0x00002729, 0x000025c1, 0x00002866, 0x00000001, 0x900001f0 },
FinalRegs = new uint[] { 0x00002b17, 0x0000272f, 0x00002483, 0x0000284c, 0x0000287f, 0x0000238f, 0x000022e1, 0x00002259, 0x0000249d, 0x00002e3f, 0x00002323, 0x00002729, 0x000025c1, 0x00002866, 0x00000001, 0x900001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x22e0, Value: 0x2fe0), (Address: 0x22e2, Value: 0x0027), (Address: 0x22e4, Value: 0x2200) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf844, 0x3f11, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000028e1, 0x00002d48, 0x000027d6, 0x000023ac, 0x000027bb, 0x000026cf, 0x000023c1, 0x00002633, 0x0000214b, 0x00002434, 0x0000239a, 0x000025c6, 0x00002148, 0x00002d1f, 0x00000001, 0x300001f0 },
FinalRegs = new uint[] { 0x000028e1, 0x00002d48, 0x000027d6, 0x000023ac, 0x000027cc, 0x000026cf, 0x000023c1, 0x00002633, 0x0000214b, 0x00002434, 0x0000239a, 0x000025c6, 0x00002148, 0x00002d1f, 0x00000001, 0x300001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x27cc, Value: 0x23ac), (Address: 0x27ce, Value: 0x0000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf847, 0x09c2, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000248b, 0x00002396, 0x000023c5, 0x00002be0, 0x0000237d, 0x00002191, 0x00002da0, 0x0000211c, 0x00002d24, 0x000021e6, 0x000024ff, 0x00002268, 0x00002968, 0x0000244d, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0x0000248b, 0x00002396, 0x000023c5, 0x00002be0, 0x0000237d, 0x00002191, 0x00002da0, 0x0000205a, 0x00002d24, 0x000021e6, 0x000024ff, 0x00002268, 0x00002968, 0x0000244d, 0x00000001, 0x800001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x211c, Value: 0x248b), (Address: 0x211e, Value: 0x0000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf84d, 0x7f23, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000025b0, 0x0000260e, 0x00002343, 0x00002e36, 0x000024c5, 0x000029bc, 0x0000278e, 0x00002b63, 0x00002ce7, 0x000029af, 0x000023bf, 0x00002475, 0x00002197, 0x00002c33, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x000025b0, 0x0000260e, 0x00002343, 0x00002e36, 0x000024c5, 0x000029bc, 0x0000278e, 0x00002b63, 0x00002ce7, 0x000029af, 0x000023bf, 0x00002475, 0x00002197, 0x00002c56, 0x00000001, 0x200001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2c56, Value: 0x2b63), (Address: 0x2c58, Value: 0x0000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf843, 0x9d24, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002ce4, 0x00002e0e, 0x000026d5, 0x000025fb, 0x00002b78, 0x0000215a, 0x00002af7, 0x0000259c, 0x00002645, 0x000027dc, 0x00002163, 0x000028f5, 0x000029df, 0x0000230b, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x00002ce4, 0x00002e0e, 0x000026d5, 0x000025d7, 0x00002b78, 0x0000215a, 0x00002af7, 0x0000259c, 0x00002645, 0x000027dc, 0x00002163, 0x000028f5, 0x000029df, 0x0000230b, 0x00000001, 0x500001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x25d6, Value: 0xdcd6), (Address: 0x25d8, Value: 0x0027), (Address: 0x25da, Value: 0x2500) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf849, 0xdc1a, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002d98, 0x0000254a, 0x00002540, 0x00002324, 0x0000264e, 0x00002523, 0x0000271f, 0x00002875, 0x000023b3, 0x00002680, 0x00002223, 0x000022bf, 0x000025f4, 0x00002d81, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0x00002d98, 0x0000254a, 0x00002540, 0x00002324, 0x0000264e, 0x00002523, 0x0000271f, 0x00002875, 0x000023b3, 0x00002680, 0x00002223, 0x000022bf, 0x000025f4, 0x00002d81, 0x00000001, 0x700001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2666, Value: 0x2d81), (Address: 0x2668, Value: 0x0000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf849, 0x0cd1, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000255a, 0x00002655, 0x00002276, 0x000022e4, 0x00002eef, 0x00002e99, 0x00002b55, 0x00002a40, 0x00002661, 0x00002dbd, 0x00002687, 0x000024e1, 0x000023ea, 0x00002b88, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x0000255a, 0x00002655, 0x00002276, 0x000022e4, 0x00002eef, 0x00002e99, 0x00002b55, 0x00002a40, 0x00002661, 0x00002dbd, 0x00002687, 0x000024e1, 0x000023ea, 0x00002b88, 0x00000001, 0xc00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2cec, Value: 0x255a), (Address: 0x2cee, Value: 0x0000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf847, 0x7c96, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000027f6, 0x0000222a, 0x000024e1, 0x00002a2d, 0x00002ee8, 0x000023f2, 0x000029de, 0x00002a53, 0x000029da, 0x00002d2c, 0x00002d6f, 0x000026b8, 0x00002777, 0x00002e3a, 0x00000001, 0xf00001f0 },
FinalRegs = new uint[] { 0x000027f6, 0x0000222a, 0x000024e1, 0x00002a2d, 0x00002ee8, 0x000023f2, 0x000029de, 0x00002a53, 0x000029da, 0x00002d2c, 0x00002d6f, 0x000026b8, 0x00002777, 0x00002e3a, 0x00000001, 0xf00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x29bc, Value: 0x53bc), (Address: 0x29be, Value: 0x002a), (Address: 0x29c0, Value: 0x2900) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf84d, 0x8cbd, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002a58, 0x00002a59, 0x00002dfd, 0x00002ba8, 0x00002929, 0x00002146, 0x00002706, 0x000025f3, 0x000023d7, 0x0000221f, 0x000027ae, 0x00002a6e, 0x00002824, 0x00002357, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x00002a58, 0x00002a59, 0x00002dfd, 0x00002ba8, 0x00002929, 0x00002146, 0x00002706, 0x000025f3, 0x000023d7, 0x0000221f, 0x000027ae, 0x00002a6e, 0x00002824, 0x00002357, 0x00000001, 0x600001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x229a, Value: 0x23d7), (Address: 0x229c, Value: 0x0000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf846, 0xacaf, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000284f, 0x00002def, 0x0000292f, 0x000021e8, 0x0000274e, 0x00002518, 0x00002538, 0x00002375, 0x00002d28, 0x0000229a, 0x0000255f, 0x00002eca, 0x00002e15, 0x000021aa, 0x00000001, 0x100001f0 },
@@ -299,35 +300,35 @@ namespace Ryujinx.Tests.Cpu
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2488, Value: 0x5f88), (Address: 0x248a, Value: 0x0025), (Address: 0x248c, Value: 0x2400) },
},
// STR (imm12)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8cc, 0x1a6e, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x500001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2a6e, Value: 0x2000), (Address: 0x2a70, Value: 0x0000) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8c9, 0xcfc1, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xe00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2fc0, Value: 0x00c0), (Address: 0x2fc2, Value: 0x0020), (Address: 0x2fc4, Value: 0x2f00) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8c3, 0xb5dd, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x600001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x25dc, Value: 0x00dc), (Address: 0x25de, Value: 0x0020), (Address: 0x25e0, Value: 0x2500) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8c0, 0x69e9, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xe00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x29e8, Value: 0x00e8), (Address: 0x29ea, Value: 0x0020), (Address: 0x29ec, Value: 0x2900) },
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8cd, 0x028f, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x600001f0 },
@@ -335,186 +336,186 @@ namespace Ryujinx.Tests.Cpu
MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x228e, Value: 0x008e), (Address: 0x2290, Value: 0x0020), (Address: 0x2292, Value: 0x2200) },
},
// LDRB (imm8)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf816, 0x1c48, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002cb8, 0x00002345, 0x00002ebc, 0x00002db8, 0x000021d4, 0x000026e4, 0x00002458, 0x000029e3, 0x000028d2, 0x000027f4, 0x000023d6, 0x00002def, 0x0000285c, 0x00002d06, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x00002cb8, 0x00000010, 0x00002ebc, 0x00002db8, 0x000021d4, 0x000026e4, 0x00002458, 0x000029e3, 0x000028d2, 0x000027f4, 0x000023d6, 0x00002def, 0x0000285c, 0x00002d06, 0x00000001, 0x600001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf815, 0x2d6e, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000021e4, 0x00002425, 0x00002e42, 0x00002a58, 0x00002708, 0x00002965, 0x00002a1d, 0x00002ed5, 0x00002cc4, 0x000026e1, 0x00002b4b, 0x00002ade, 0x00002824, 0x00002975, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0x000021e4, 0x00002425, 0x00000028, 0x00002a58, 0x00002708, 0x000028f7, 0x00002a1d, 0x00002ed5, 0x00002cc4, 0x000026e1, 0x00002b4b, 0x00002ade, 0x00002824, 0x00002975, 0x00000001, 0x100001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf818, 0x0d33, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002492, 0x0000214d, 0x00002827, 0x000021af, 0x0000215e, 0x000028d6, 0x000024ec, 0x00002984, 0x0000297b, 0x000024b5, 0x000024ca, 0x0000298f, 0x00002339, 0x00002b7e, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x00000048, 0x0000214d, 0x00002827, 0x000021af, 0x0000215e, 0x000028d6, 0x000024ec, 0x00002984, 0x00002948, 0x000024b5, 0x000024ca, 0x0000298f, 0x00002339, 0x00002b7e, 0x00000001, 0xd00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf810, 0xbff3, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002ea6, 0x000024fa, 0x00002346, 0x00002748, 0x0000283f, 0x00002770, 0x000023e3, 0x000021aa, 0x0000214a, 0x00002d58, 0x00002159, 0x000022e7, 0x00002242, 0x00002728, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x00002f99, 0x000024fa, 0x00002346, 0x00002748, 0x0000283f, 0x00002770, 0x000023e3, 0x000021aa, 0x0000214a, 0x00002d58, 0x00002159, 0x0000002f, 0x00002242, 0x00002728, 0x00000001, 0x600001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
// LDRB (imm12)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf892, 0xcc8f, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x0000002c, 0x00002000, 0x00000001, 0x100001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf89a, 0x7fdc, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x000000dc, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x200001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf890, 0x5f9f, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x0000002f, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x800001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf894, 0xdda1, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x900001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x0000002d, 0x00000001, 0x900001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf890, 0xc281, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000022, 0x00002000, 0x00000001, 0x100001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
// LDRH (imm8)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf834, 0x89d8, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002a9e, 0x00002d84, 0x00002e9b, 0x00002e7f, 0x000024a2, 0x00002b7b, 0x00002e3b, 0x0000299a, 0x00002dff, 0x00002a9e, 0x000027b2, 0x00002a90, 0x00002883, 0x0000288d, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x00002a9e, 0x00002d84, 0x00002e9b, 0x00002e7f, 0x000023ca, 0x00002b7b, 0x00002e3b, 0x0000299a, 0x000024a2, 0x00002a9e, 0x000027b2, 0x00002a90, 0x00002883, 0x0000288d, 0x00000001, 0x500001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf833, 0x6be4, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000028bd, 0x00002b0e, 0x00002bc1, 0x00002a83, 0x00002293, 0x00002c7c, 0x00002bfe, 0x00002eb7, 0x0000299b, 0x000026e6, 0x0000219c, 0x00002d5e, 0x00002cd4, 0x000026cf, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x000028bd, 0x00002b0e, 0x00002bc1, 0x00002b67, 0x00002293, 0x00002c7c, 0x0000842a, 0x00002eb7, 0x0000299b, 0x000026e6, 0x0000219c, 0x00002d5e, 0x00002cd4, 0x000026cf, 0x00000001, 0xd00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf83d, 0x1bca, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000250e, 0x00002776, 0x000029e5, 0x0000276e, 0x00002c6b, 0x00002712, 0x00002a85, 0x00002d56, 0x000024c0, 0x00002d86, 0x0000254a, 0x00002549, 0x00002795, 0x00002e97, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x0000250e, 0x0000982e, 0x000029e5, 0x0000276e, 0x00002c6b, 0x00002712, 0x00002a85, 0x00002d56, 0x000024c0, 0x00002d86, 0x0000254a, 0x00002549, 0x00002795, 0x00002f61, 0x00000001, 0x200001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
// LDRH (imm12)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8b7, 0x92fc, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x000022fc, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xa00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8ba, 0xadd9, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x0000da2d, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xa00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8bb, 0x0bb0, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x00002bb0, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0xd00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8b8, 0xc3f8, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x000023f8, 0x00002000, 0x00000001, 0x600001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
// LDR (imm8)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf85b, 0x3fd1, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002a19, 0x00002e5b, 0x0000231b, 0x000021fa, 0x00002e95, 0x00002bd5, 0x00002e9c, 0x00002dfa, 0x000021d8, 0x00002ce1, 0x00002318, 0x00002735, 0x0000247d, 0x00002436, 0x00000001, 0xf00001f0 },
FinalRegs = new uint[] { 0x00002a19, 0x00002e5b, 0x0000231b, 0x28082806, 0x00002e95, 0x00002bd5, 0x00002e9c, 0x00002dfa, 0x000021d8, 0x00002ce1, 0x00002318, 0x00002806, 0x0000247d, 0x00002436, 0x00000001, 0xf00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf854, 0xab9e, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x0000214f, 0x00002578, 0x00002a98, 0x000021b0, 0x00002ebb, 0x0000284a, 0x00002319, 0x00002581, 0x00002179, 0x00002594, 0x00002373, 0x000028f4, 0x00002ec5, 0x00002e0a, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0x0000214f, 0x00002578, 0x00002a98, 0x000021b0, 0x00002f59, 0x0000284a, 0x00002319, 0x00002581, 0x00002179, 0x00002594, 0xbe2ebc2e, 0x000028f4, 0x00002ec5, 0x00002e0a, 0x00000001, 0xb00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf852, 0x6d2d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002e27, 0x00002676, 0x00002bde, 0x000022d9, 0x00002362, 0x00002d4b, 0x00002dab, 0x000022b6, 0x0000229c, 0x00002507, 0x00002848, 0x0000225f, 0x00002ac2, 0x000023c3, 0x00000001, 0xf00001f0 },
FinalRegs = new uint[] { 0x00002e27, 0x00002676, 0x00002bb1, 0x000022d9, 0x00002362, 0x00002d4b, 0xb42bb22b, 0x000022b6, 0x0000229c, 0x00002507, 0x00002848, 0x0000225f, 0x00002ac2, 0x000023c3, 0x00000001, 0xf00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf850, 0x8da5, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002559, 0x0000285e, 0x000021de, 0x00002223, 0x000023ff, 0x00002e05, 0x00002bf3, 0x000024a5, 0x00002124, 0x00002768, 0x00002a14, 0x0000219e, 0x00002739, 0x00002e3c, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x000024b4, 0x0000285e, 0x000021de, 0x00002223, 0x000023ff, 0x00002e05, 0x00002bf3, 0x000024a5, 0x24b624b4, 0x00002768, 0x00002a14, 0x0000219e, 0x00002739, 0x00002e3c, 0x00000001, 0xd00001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf857, 0x19f6, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x000027f5, 0x0000285e, 0x000025f6, 0x00002e22, 0x00002224, 0x00002870, 0x00002ecc, 0x000024cf, 0x00002711, 0x0000241b, 0x00002ddf, 0x00002545, 0x000028ca, 0x000023c5, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0x000027f5, 0xd224d024, 0x000025f6, 0x00002e22, 0x00002224, 0x00002870, 0x00002ecc, 0x000023d9, 0x00002711, 0x0000241b, 0x00002ddf, 0x00002545, 0x000028ca, 0x000023c5, 0x00000001, 0x400001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
// LDR (imm12)
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8d1, 0xc65e, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x2660265e, 0x00002000, 0x00000001, 0x000001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8db, 0xd09b, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x9e209c20, 0x00000001, 0x800001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8d2, 0x6fde, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x900001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x2fe02fde, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x900001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
new PrecomputedMemoryThumbTestCase()
new()
{
Instructions = new ushort[] { 0xf8dc, 0x3de5, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x00002000, 0x00002000, 0x00002000, 0xe82de62d, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00002000, 0x00000001, 0x500001f0 },
MemoryDelta = new (ulong Address, ushort Value)[] {},
MemoryDelta = Array.Empty<(ulong Address, ushort Value)>(),
},
};
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -10,22 +10,24 @@ namespace Ryujinx.Tests.Cpu
{
internal class EnvironmentTests
{
#pragma warning disable IDE0052 // Remove unread private member
private static Translator _translator;
#pragma warning restore IDE0052
private void EnsureTranslator()
private static void EnsureTranslator()
{
// Create a translator, as one is needed to register the signal handler or emit methods.
_translator ??= new Translator(new JitMemoryAllocator(), new MockMemoryManager(), true);
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private float GetDenormal()
private static float GetDenormal()
{
return BitConverter.Int32BitsToSingle(1);
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private float GetZero()
private static float GetZero()
{
return BitConverter.Int32BitsToSingle(0);
}
@@ -53,7 +55,7 @@ namespace Ryujinx.Tests.Cpu
if (test < 4f)
{
throw new System.Exception("Sanity check.");
throw new Exception("Sanity check.");
}
isFz = GetDenormal() + GetZero() == 0f;
@@ -62,7 +64,7 @@ namespace Ryujinx.Tests.Cpu
{
if (test >= 4f)
{
throw new System.Exception("Always throws.");
throw new Exception("Always throws.");
}
}
catch

View File

@@ -6,5 +6,5 @@ namespace Ryujinx.Tests.Cpu
public uint[] StartRegs;
public uint[] FinalRegs;
public (ulong Address, ushort Value)[] MemoryDelta;
};
}
}
}

View File

@@ -6,4 +6,4 @@
public uint[] StartRegs;
public uint[] FinalRegs;
}
}
}

View File

@@ -21,8 +21,7 @@ namespace Ryujinx.Tests.HLE
[Test]
public void StripUnicodeControlCodes_Passthrough()
{
string[] prompts = new string[]
{
string[] prompts = {
"Please name him.",
"Name her, too.",
"Name your friend.",

View File

@@ -11,7 +11,7 @@ namespace Ryujinx.Tests.Memory
public MemoryManagerType Type => MemoryManagerType.HostMappedUnsafe;
#pragma warning disable CS0067
#pragma warning disable CS0067 // The event is never used
public event Action<ulong, ulong> UnmapEvent;
#pragma warning restore CS0067

View File

@@ -20,7 +20,7 @@ namespace Ryujinx.Tests.Memory
{
private static Translator _translator;
private (MemoryBlock virt, MemoryBlock mirror, MemoryEhMeilleure exceptionHandler) GetVirtual(ulong asSize)
private static (MemoryBlock virt, MemoryBlock mirror, MemoryEhMeilleure exceptionHandler) GetVirtual(ulong asSize)
{
MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
@@ -33,7 +33,7 @@ namespace Ryujinx.Tests.Memory
return (addressSpace, addressSpaceMirror, exceptionHandler);
}
private int CountThreads(ref PartialUnmapState state)
private static int CountThreads(ref PartialUnmapState state)
{
int count = 0;
@@ -50,7 +50,7 @@ namespace Ryujinx.Tests.Memory
return count;
}
private void EnsureTranslator()
private static void EnsureTranslator()
{
// Create a translator, as one is needed to register the signal handler or emit methods.
_translator ??= new Translator(new JitMemoryAllocator(), new MockMemoryManager(), true);
@@ -239,7 +239,7 @@ namespace Ryujinx.Tests.Memory
var writeFunc = TestMethods.GenerateDebugNativeWriteLoop();
IntPtr writePtr = mainMemory.GetPointer(vaSize - 0x1000, 4);
Thread testThread = new Thread(() =>
Thread testThread = new(() =>
{
writeFunc(statePtr, writePtr);
});
@@ -283,7 +283,7 @@ namespace Ryujinx.Tests.Memory
[Test]
// Only test in Windows, as this is only used on Windows and uses Windows APIs for trimming.
[Platform("Win")]
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")]
[SuppressMessage("Interoperability", "CA1416: Validate platform compatibility")]
public void ThreadLocalMap()
{
PartialUnmapState.Reset();
@@ -465,4 +465,4 @@ namespace Ryujinx.Tests.Memory
Assert.False(error);
}
}
}
}

View File

@@ -10,7 +10,7 @@ namespace Ryujinx.Tests.Collections
[Test]
public void EnsureAddIntegrity()
{
TreeDictionary<int, int> dictionary = new TreeDictionary<int, int>();
TreeDictionary<int, int> dictionary = new();
Assert.AreEqual(dictionary.Count, 0);
@@ -35,7 +35,7 @@ namespace Ryujinx.Tests.Collections
* 5 11
*
*/
Assert.AreEqual(list.Count, dictionary.Count);
Assert.AreEqual(list[0].Key, 2);
Assert.AreEqual(list[1].Key, 1);
@@ -49,7 +49,7 @@ namespace Ryujinx.Tests.Collections
[Test]
public void EnsureRemoveIntegrity()
{
TreeDictionary<int, int> dictionary = new TreeDictionary<int, int>();
TreeDictionary<int, int> dictionary = new();
Assert.AreEqual(dictionary.Count, 0);
@@ -165,7 +165,7 @@ namespace Ryujinx.Tests.Collections
[Test]
public void EnsureOverwriteIntegrity()
{
TreeDictionary<int, int> dictionary = new TreeDictionary<int, int>();
TreeDictionary<int, int> dictionary = new();
Assert.AreEqual(dictionary.Count, 0);

View File

@@ -6,4 +6,4 @@ namespace Ryujinx.Ui.App.Common
{
public ApplicationData AppData { get; set; }
}
}
}

View File

@@ -4,7 +4,7 @@ namespace Ryujinx.Ui.App.Common
{
public class ApplicationCountUpdatedEventArgs : EventArgs
{
public int NumAppsFound { get; set; }
public int NumAppsFound { get; set; }
public int NumAppsLoaded { get; set; }
}
}
}

View File

@@ -18,19 +18,19 @@ namespace Ryujinx.Ui.App.Common
{
public class ApplicationData
{
public bool Favorite { get; set; }
public byte[] Icon { get; set; }
public string TitleName { get; set; }
public string TitleId { get; set; }
public string Developer { get; set; }
public string Version { get; set; }
public string TimePlayed { get; set; }
public double TimePlayedNum { get; set; }
public DateTime? LastPlayed { get; set; }
public string FileExtension { get; set; }
public string FileSize { get; set; }
public double FileSizeBytes { get; set; }
public string Path { get; set; }
public bool Favorite { get; set; }
public byte[] Icon { get; set; }
public string TitleName { get; set; }
public string TitleId { get; set; }
public string Developer { get; set; }
public string Version { get; set; }
public string TimePlayed { get; set; }
public double TimePlayedNum { get; set; }
public DateTime? LastPlayed { get; set; }
public string FileExtension { get; set; }
public string FileSize { get; set; }
public double FileSizeBytes { get; set; }
public string Path { get; set; }
public BlitStruct<ApplicationControlProperty> ControlHolder { get; set; }
[JsonIgnore]
@@ -159,7 +159,7 @@ namespace Ryujinx.Ui.App.Common
codeFs.OpenFile(ref nsoFile.Ref, $"/{MainExeFs}".ToU8Span(), OpenMode.Read).ThrowIfFailure();
NsoReader reader = new NsoReader();
NsoReader reader = new();
reader.Initialize(nsoFile.Release().AsStorage().AsFile(OpenMode.Read)).ThrowIfFailure();
return BitConverter.ToString(reader.Header.ModuleId.ItemsRo.ToArray()).Replace("-", "").ToUpper()[..16];

Some files were not shown because too many files have changed in this diff Show More