Compare commits

...

5 Commits

Author SHA1 Message Date
dependabot[bot]
f978d3726a nuget: bump System.Management from 7.0.1 to 7.0.2 (#5302)
Bumps [System.Management](https://github.com/dotnet/runtime) from 7.0.1 to 7.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v7.0.1...v7.0.2)

---
updated-dependencies:
- dependency-name: System.Management
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 18:21:17 +02:00
Mary
6f28c4abad test: Make tests runnable on system without 4KiB page size (#5184)
* ARMeilleure: Do not hardcode 4KiB page size in JitCache

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Memory.Tests

Fix running tests on Asahi Linux with 16KiB pages.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix running tests on Asahi Linux.

Test runner still crash when trying to run all test suite.

* test: Do not hardcode page size to 4KiB for Ryujinx.Tests.Cpu

Fix somecrashes on Asahi Linux.

* test: Ignore Vshl test on ARM64 due to unicorn crashes

* test: Workaround hardcoded size on some tests

Change mapping of code and data in case of non 4KiB configuration.

* test: Make CpuTestT32Flow depends on code address

Fix failure with different page size.

* test: Disable CpuTestThumb.TestRandomTestCases when page size isn't 4KiB

The test data needs to be reevaluated to take different page size into account.

* Address gdkchan's comments
2023-06-14 18:02:41 +02:00
gdkchan
105c9712c1 Fix Arm32 double to int/uint conversion on Arm64 (#5292)
* Fix Arm32 double to int/uint conversion on Arm64

* PPTC version bump
2023-06-14 00:57:02 -03:00
Kurochi51
4d804ed45e Mod Loader: Stop loading mods from folders that don't exactly match titleId (#5298)
* Stop loading mods from folders that don't exactly match titleId

* What the worst that can happen?
2023-06-13 20:47:33 +02:00
Mary
4a27d29412 infra: Sync paths-ignore with release job and attempt to fix review assign 2023-06-13 11:51:22 +02:00
15 changed files with 169 additions and 88 deletions

View File

@@ -5,13 +5,12 @@ on:
inputs: {} inputs: {}
pull_request: pull_request:
branches: [ master ] branches: [ master ]
paths: paths-ignore:
- '!.github/**' - '.github/**'
- '!*.yml' - '*.yml'
- '!*.json' - '*.json'
- '!*.config' - '*.config'
- '!README.md' - 'README.md'
- '.github/workflows/*.yml'
concurrency: concurrency:
group: pr-checks-${{ github.event.number }} group: pr-checks-${{ github.event.number }}

View File

@@ -1,13 +1,16 @@
name: "Pull Request Triage" name: "Pull Request Triage"
on: on:
pull_request_target: pull_request_target:
types: [opened, ready_for_review]
jobs: jobs:
triage: triage:
permissions: permissions:
contents: read contents: read
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Update labels based on changes - name: Update labels based on changes
uses: actions/labeler@v4 uses: actions/labeler@v4
@@ -19,40 +22,33 @@ jobs:
uses: kentaro-m/auto-assign-action@v1.2.5 uses: kentaro-m/auto-assign-action@v1.2.5
with: with:
configuration-path: '.github/assign/audio.yml' configuration-path: '.github/assign/audio.yml'
if: github.event.action == 'opened'
- name: Auto Assign [CPU] - name: Auto Assign [CPU]
uses: kentaro-m/auto-assign-action@v1.2.5 uses: kentaro-m/auto-assign-action@v1.2.5
with: with:
configuration-path: '.github/assign/cpu.yml' configuration-path: '.github/assign/cpu.yml'
if: github.event.action == 'opened'
- name: Auto Assign [GPU] - name: Auto Assign [GPU]
uses: kentaro-m/auto-assign-action@v1.2.5 uses: kentaro-m/auto-assign-action@v1.2.5
with: with:
configuration-path: '.github/assign/gpu.yml' configuration-path: '.github/assign/gpu.yml'
if: github.event.action == 'opened'
- name: Auto Assign [GUI] - name: Auto Assign [GUI]
uses: kentaro-m/auto-assign-action@v1.2.5 uses: kentaro-m/auto-assign-action@v1.2.5
with: with:
configuration-path: '.github/assign/gui.yml' configuration-path: '.github/assign/gui.yml'
if: github.event.action == 'opened'
- name: Auto Assign [Horizon] - name: Auto Assign [Horizon]
uses: kentaro-m/auto-assign-action@v1.2.5 uses: kentaro-m/auto-assign-action@v1.2.5
with: with:
configuration-path: '.github/assign/horizon.yml' configuration-path: '.github/assign/horizon.yml'
if: github.event.action == 'opened'
- name: Auto Assign [Infra] - name: Auto Assign [Infra]
uses: kentaro-m/auto-assign-action@v1.2.5 uses: kentaro-m/auto-assign-action@v1.2.5
with: with:
configuration-path: '.github/assign/infra.yml' configuration-path: '.github/assign/infra.yml'
if: github.event.action == 'opened'
- name: Auto Assign [Global] - name: Auto Assign [Global]
uses: kentaro-m/auto-assign-action@v1.2.5 uses: kentaro-m/auto-assign-action@v1.2.5
with: with:
configuration-path: '.github/assign/global.yml' configuration-path: '.github/assign/global.yml'
if: github.event.action == 'opened'

View File

@@ -46,7 +46,7 @@
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" /> <PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" /> <PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" /> <PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
<PackageVersion Include="System.Management" Version="7.0.1" /> <PackageVersion Include="System.Management" Version="7.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" /> <PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" /> <PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup> </ItemGroup>

View File

@@ -165,7 +165,7 @@ namespace ARMeilleure.Instructions
{ {
Operand m = GetVecA32(op.Vm >> 1); Operand m = GetVecA32(op.Vm >> 1);
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, doubleSize); Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble; Intrinsic inst = (unsigned ? Intrinsic.Arm64FcvtzuGp : Intrinsic.Arm64FcvtzsGp) | Intrinsic.Arm64VDouble;
@@ -175,7 +175,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS); InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, unsigned ? Intrinsic.Arm64FcvtzuS : Intrinsic.Arm64FcvtzsS, false);
} }
} }
else if (!roundWithFpscr && Optimizations.UseSse41) else if (!roundWithFpscr && Optimizations.UseSse41)
@@ -259,6 +259,41 @@ namespace ARMeilleure.Instructions
Intrinsic inst; Intrinsic inst;
if (Optimizations.UseAdvSimd) if (Optimizations.UseAdvSimd)
{
bool doubleSize = floatSize == OperandType.FP64;
if (doubleSize)
{
Operand m = GetVecA32(op.Vm >> 1);
Operand toConvert = InstEmitSimdHelper32Arm64.EmitExtractScalar(context, m, op.Vm, true);
if (unsigned)
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtauGp,
0b01 => Intrinsic.Arm64FcvtnuGp,
0b10 => Intrinsic.Arm64FcvtpuGp,
0b11 => Intrinsic.Arm64FcvtmuGp,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
}
else
{
inst = rm switch {
0b00 => Intrinsic.Arm64FcvtasGp,
0b01 => Intrinsic.Arm64FcvtnsGp,
0b10 => Intrinsic.Arm64FcvtpsGp,
0b11 => Intrinsic.Arm64FcvtmsGp,
_ => throw new ArgumentOutOfRangeException(nameof(rm))
};
}
Operand asInteger = context.AddIntrinsicInt(inst | Intrinsic.Arm64VDouble, toConvert);
InsertScalar(context, op.Vd, asInteger);
}
else
{ {
if (unsigned) if (unsigned)
{ {
@@ -283,6 +318,7 @@ namespace ARMeilleure.Instructions
InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst); InstEmitSimdHelper32Arm64.EmitScalarUnaryOpF32(context, inst);
} }
}
else if (Optimizations.UseSse41) else if (Optimizations.UseSse41)
{ {
EmitSse41ConvertInt32(context, RMToRoundMode(rm), !unsigned); EmitSse41ConvertInt32(context, RMToRoundMode(rm), !unsigned);

View File

@@ -192,11 +192,10 @@ namespace ARMeilleure.Instructions
EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m)); EmitVectorTernaryOpSimd32(context, (d, n, m) => context.AddIntrinsic(inst, d, n, m));
} }
public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc) public static void EmitScalarUnaryOpSimd32(ArmEmitterContext context, Func1I scalarFunc, bool doubleSize)
{ {
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
bool doubleSize = (op.Size & 1) != 0;
int shift = doubleSize ? 1 : 2; int shift = doubleSize ? 1 : 2;
Operand m = GetVecA32(op.Vm >> shift); Operand m = GetVecA32(op.Vm >> shift);
Operand d = GetVecA32(op.Vd >> shift); Operand d = GetVecA32(op.Vd >> shift);
@@ -215,8 +214,13 @@ namespace ARMeilleure.Instructions
{ {
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
inst |= ((op.Size & 1) != 0 ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128; EmitScalarUnaryOpF32(context, inst, (op.Size & 1) != 0);
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m)); }
public static void EmitScalarUnaryOpF32(ArmEmitterContext context, Intrinsic inst, bool doubleSize)
{
inst |= (doubleSize ? Intrinsic.Arm64VDouble : Intrinsic.Arm64VFloat) | Intrinsic.Arm64V128;
EmitScalarUnaryOpSimd32(context, (m) => (inst == 0) ? m : context.AddIntrinsic(inst, m), doubleSize);
} }
public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc) public static void EmitScalarBinaryOpSimd32(ArmEmitterContext context, Func2I scalarFunc)

View File

@@ -2,6 +2,7 @@ using ARMeilleure.CodeGen;
using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.CodeGen.Unwinding;
using ARMeilleure.Memory; using ARMeilleure.Memory;
using ARMeilleure.Native; using ARMeilleure.Native;
using Ryujinx.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@@ -12,8 +13,8 @@ namespace ARMeilleure.Translation.Cache
{ {
static partial class JitCache static partial class JitCache
{ {
private const int PageSize = 4 * 1024; private static readonly int PageSize = (int)MemoryBlock.GetPageSize();
private const int PageMask = PageSize - 1; private static readonly int PageMask = PageSize - 1;
private const int CodeAlignment = 4; // Bytes. private const int CodeAlignment = 4; // Bytes.
private const int CacheSize = 2047 * 1024 * 1024; private const int CacheSize = 2047 * 1024 * 1024;

View File

@@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 5281; //! To be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 5292; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0"; private const string ActualDir = "0";
private const string BackupDir = "1"; private const string BackupDir = "1";

View File

@@ -154,7 +154,7 @@ namespace Ryujinx.HLE.HOS
} }
private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId) private static DirectoryInfo FindTitleDir(DirectoryInfo contentsDir, string titleId)
=> contentsDir.EnumerateDirectories($"{titleId}*", DirEnumOptions).FirstOrDefault(); => contentsDir.EnumerateDirectories(titleId, DirEnumOptions).FirstOrDefault();
private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId) private static void AddModsFromDirectory(ModCache mods, DirectoryInfo dir, string titleId)
{ {

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Tests.Memory
{ {
public class Tests public class Tests
{ {
private const ulong MemorySize = 0x8000; private static readonly ulong MemorySize = MemoryBlock.GetPageSize() * 8;
private MemoryBlock _memoryBlock; private MemoryBlock _memoryBlock;
@@ -44,14 +44,17 @@ namespace Ryujinx.Tests.Memory
[Platform(Exclude = "MacOsX")] [Platform(Exclude = "MacOsX")]
public void Test_Alias() public void Test_Alias()
{ {
using MemoryBlock backing = new MemoryBlock(0x10000, MemoryAllocationFlags.Mirrorable); ulong pageSize = MemoryBlock.GetPageSize();
using MemoryBlock toAlias = new MemoryBlock(0x10000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible); ulong blockSize = MemoryBlock.GetPageSize() * 16;
toAlias.MapView(backing, 0x1000, 0, 0x4000); using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
toAlias.UnmapView(backing, 0x3000, 0x1000); using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
toAlias.MapView(backing, pageSize, 0, pageSize * 4);
toAlias.UnmapView(backing, pageSize * 3, pageSize);
toAlias.Write(0, 0xbadc0de); toAlias.Write(0, 0xbadc0de);
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, 0x1000), 0xbadc0de); Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (int)pageSize), 0xbadc0de);
} }
[Test] [Test]
@@ -59,8 +62,12 @@ namespace Ryujinx.Tests.Memory
[Platform(Exclude = "MacOsX")] [Platform(Exclude = "MacOsX")]
public void Test_AliasRandom() public void Test_AliasRandom()
{ {
using MemoryBlock backing = new MemoryBlock(0x80000, MemoryAllocationFlags.Mirrorable); ulong pageSize = MemoryBlock.GetPageSize();
using MemoryBlock toAlias = new MemoryBlock(0x80000, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible); int pageBits = (int)ulong.Log2(pageSize);
ulong blockSize = MemoryBlock.GetPageSize() * 128;
using MemoryBlock backing = new MemoryBlock(blockSize, MemoryAllocationFlags.Mirrorable);
using MemoryBlock toAlias = new MemoryBlock(blockSize, MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible);
Random rng = new Random(123); Random rng = new Random(123);
@@ -72,16 +79,16 @@ namespace Ryujinx.Tests.Memory
if ((rng.Next() & 1) != 0) if ((rng.Next() & 1) != 0)
{ {
toAlias.MapView(backing, (ulong)srcPage << 12, (ulong)dstPage << 12, (ulong)pages << 12); toAlias.MapView(backing, (ulong)srcPage << pageBits, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
int offset = rng.Next(0, 0x1000 - sizeof(int)); int offset = rng.Next(0, (int)pageSize - sizeof(int));
toAlias.Write((ulong)((dstPage << 12) + offset), 0xbadc0de); toAlias.Write((ulong)((dstPage << pageBits) + offset), 0xbadc0de);
Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << 12) + offset), 0xbadc0de); Assert.AreEqual(Marshal.ReadInt32(backing.Pointer, (srcPage << pageBits) + offset), 0xbadc0de);
} }
else else
{ {
toAlias.UnmapView(backing, (ulong)dstPage << 12, (ulong)pages << 12); toAlias.UnmapView(backing, (ulong)dstPage << pageBits, (ulong)pages << pageBits);
} }
} }
} }
@@ -91,7 +98,7 @@ namespace Ryujinx.Tests.Memory
[Platform(Exclude = "MacOsX")] [Platform(Exclude = "MacOsX")]
public void Test_AliasMapLeak() public void Test_AliasMapLeak()
{ {
ulong pageSize = 4096; ulong pageSize = MemoryBlock.GetPageSize();
ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that. ulong size = 100000 * pageSize; // The mappings limit on Linux is usually around 65K, so let's make sure we are above that.
using MemoryBlock backing = new MemoryBlock(pageSize, MemoryAllocationFlags.Mirrorable); using MemoryBlock backing = new MemoryBlock(pageSize, MemoryAllocationFlags.Mirrorable);

View File

@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
[TestFixture] [TestFixture]
public class CpuTest public class CpuTest
{ {
protected const ulong Size = 0x1000; protected static readonly ulong Size = MemoryBlock.GetPageSize();
protected const ulong CodeBaseAddress = 0x1000; protected static ulong CodeBaseAddress = Size;
protected const ulong DataBaseAddress = CodeBaseAddress + Size; protected static ulong DataBaseAddress = CodeBaseAddress + Size;
private static bool Ignore_FpcrFz = false; private static bool Ignore_FpcrFz = false;
private static bool Ignore_FpcrDn = false; private static bool Ignore_FpcrDn = false;
@@ -39,12 +39,24 @@ namespace Ryujinx.Tests.Cpu
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_currAddress = CodeBaseAddress; int pageBits = (int)ulong.Log2(Size);
_ram = new MemoryBlock(Size * 2); _ram = new MemoryBlock(Size * 2);
_memory = new MemoryManager(_ram, 1ul << 16); _memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
_memory.IncrementReferenceCount(); _memory.IncrementReferenceCount();
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
// Some tests depends on hardcoded address that were computed for 4KiB.
// We change the layout on non 4KiB platforms to keep compat here.
if (Size > 0x1000)
{
DataBaseAddress = 0;
CodeBaseAddress = Size;
}
_currAddress = CodeBaseAddress;
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
_context = CpuContext.CreateExecutionContext(); _context = CpuContext.CreateExecutionContext();
Translator.IsReadyForTranslation.Set(); Translator.IsReadyForTranslation.Set();

View File

@@ -13,9 +13,9 @@ namespace Ryujinx.Tests.Cpu
[TestFixture] [TestFixture]
public class CpuTest32 public class CpuTest32
{ {
protected const uint Size = 0x1000; protected static readonly uint Size = (uint)MemoryBlock.GetPageSize();
protected const uint CodeBaseAddress = 0x1000; protected static uint CodeBaseAddress = Size;
protected const uint DataBaseAddress = CodeBaseAddress + Size; protected static uint DataBaseAddress = CodeBaseAddress + Size;
private uint _currAddress; private uint _currAddress;
@@ -33,12 +33,24 @@ namespace Ryujinx.Tests.Cpu
[SetUp] [SetUp]
public void Setup() public void Setup()
{ {
_currAddress = CodeBaseAddress; int pageBits = (int)ulong.Log2(Size);
_ram = new MemoryBlock(Size * 2); _ram = new MemoryBlock(Size * 2);
_memory = new MemoryManager(_ram, 1ul << 16); _memory = new MemoryManager(_ram, 1ul << (pageBits + 4));
_memory.IncrementReferenceCount(); _memory.IncrementReferenceCount();
_memory.Map(CodeBaseAddress, 0, Size * 2, MemoryMapFlags.Private);
// Some tests depends on hardcoded address that were computed for 4KiB.
// We change the layout on non 4KiB platforms to keep compat here.
if (Size > 0x1000)
{
DataBaseAddress = 0;
CodeBaseAddress = Size;
}
_currAddress = CodeBaseAddress;
_memory.Map(CodeBaseAddress, 0, Size, MemoryMapFlags.Private);
_memory.Map(DataBaseAddress, Size, Size, MemoryMapFlags.Private);
_context = CpuContext.CreateExecutionContext(); _context = CpuContext.CreateExecutionContext();
_context.IsAarch32 = true; _context.IsAarch32 = true;

View File

@@ -1,6 +1,7 @@
#define SimdMemory32 #define SimdMemory32
using ARMeilleure.State; using ARMeilleure.State;
using Ryujinx.Memory;
using NUnit.Framework; using NUnit.Framework;
using System; using System;
@@ -9,6 +10,7 @@ namespace Ryujinx.Tests.Cpu
[Category("SimdMemory32")] [Category("SimdMemory32")]
public sealed class CpuTestSimdMemory32 : CpuTest32 public sealed class CpuTestSimdMemory32 : CpuTest32
{ {
private static readonly uint TestOffset = DataBaseAddress + 0x500;
#if SimdMemory32 #if SimdMemory32
private uint[] _ldStModes = private uint[] _ldStModes =
@@ -42,7 +44,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 3u)] uint n, [Range(0u, 3u)] uint n,
[Values(0x0u)] uint offset) [Values(0x0u)] uint offset)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
uint opcode = 0xf4a00000u; // VLD1.8 {D0[0]}, [R0], R0 uint opcode = 0xf4a00000u; // VLD1.8 {D0[0]}, [R0], R0
@@ -58,7 +60,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc. opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }
@@ -72,7 +74,7 @@ namespace Ryujinx.Tests.Cpu
[Values] bool t, [Values] bool t,
[Values(0x0u)] uint offset) [Values(0x0u)] uint offset)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
uint opcode = 0xf4a00c00u; // VLD1.8 {D0[0]}, [R0], R0 uint opcode = 0xf4a00c00u; // VLD1.8 {D0[0]}, [R0], R0
@@ -85,7 +87,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc. opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc.
if (t) opcode |= 1 << 5; if (t) opcode |= 1 << 5;
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }
@@ -98,7 +100,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 10u)] uint mode, [Range(0u, 10u)] uint mode,
[Values(0x0u)] uint offset) [Values(0x0u)] uint offset)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
uint opcode = 0xf4200000u; // VLD4.8 {D0, D1, D2, D3}, [R0], R0 uint opcode = 0xf4200000u; // VLD4.8 {D0, D1, D2, D3}, [R0], R0
@@ -114,7 +116,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0x10) << 18); opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12); opcode |= ((vd & 0xf) << 12);
SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); SingleOpcode(opcode, r0: TestOffset, r1: offset, sp: TestOffset);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }
@@ -128,7 +130,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 3u)] uint n, [Range(0u, 3u)] uint n,
[Values(0x0u)] uint offset) [Values(0x0u)] uint offset)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors(); (V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
@@ -146,7 +148,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc. opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc.
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500); SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }
@@ -159,7 +161,7 @@ namespace Ryujinx.Tests.Cpu
[Range(0u, 10u)] uint mode, [Range(0u, 10u)] uint mode,
[Values(0x0u)] uint offset) [Values(0x0u)] uint offset)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
(V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors(); (V128 vec1, V128 vec2, V128 vec3, V128 vec4) = GenerateTestVectors();
@@ -177,7 +179,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= ((vd & 0x10) << 18); opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12); opcode |= ((vd & 0xf) << 12);
SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500); SingleOpcode(opcode, r0: TestOffset, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: TestOffset);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }
@@ -189,7 +191,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0x1u, 0x32u)] uint regs, [Values(0x1u, 0x32u)] uint regs,
[Values] bool single) [Values] bool single)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0 uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0
@@ -225,7 +227,7 @@ namespace Ryujinx.Tests.Cpu
opcode |= regs & 0xff; opcode |= regs & 0xff;
SingleOpcode(opcode, r0: 0x2500, sp: 0x2500); SingleOpcode(opcode, r0: TestOffset, sp: TestOffset);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }
@@ -237,7 +239,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0x0u)] uint imm, [Values(0x0u)] uint imm,
[Values] bool sub) [Values] bool sub)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
uint opcode = 0xed900a00u; // VLDR.32 S0, [R0, #0] uint opcode = 0xed900a00u; // VLDR.32 S0, [R0, #0]
@@ -260,7 +262,7 @@ namespace Ryujinx.Tests.Cpu
} }
opcode |= imm & 0xff; opcode |= imm & 0xff;
SingleOpcode(opcode, r0: 0x2500); SingleOpcode(opcode, r0: TestOffset);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }
@@ -272,7 +274,7 @@ namespace Ryujinx.Tests.Cpu
[Values(0x0u)] uint imm, [Values(0x0u)] uint imm,
[Values] bool sub) [Values] bool sub)
{ {
var data = GenerateVectorSequence(0x1000); var data = GenerateVectorSequence((int)MemoryBlock.GetPageSize());
SetWorkingMemory(0, data); SetWorkingMemory(0, data);
uint opcode = 0xed800a00u; // VSTR.32 S0, [R0, #0] uint opcode = 0xed800a00u; // VSTR.32 S0, [R0, #0]
@@ -297,7 +299,7 @@ namespace Ryujinx.Tests.Cpu
(V128 vec1, V128 vec2, _, _) = GenerateTestVectors(); (V128 vec1, V128 vec2, _, _) = GenerateTestVectors();
SingleOpcode(opcode, r0: 0x2500, v0: vec1, v1: vec2); SingleOpcode(opcode, r0: TestOffset, v0: vec1, v1: vec2);
CompareAgainstUnicorn(); CompareAgainstUnicorn();
} }

View File

@@ -3,6 +3,7 @@
using ARMeilleure.State; using ARMeilleure.State;
using NUnit.Framework; using NUnit.Framework;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Ryujinx.Tests.Cpu namespace Ryujinx.Tests.Cpu
{ {
@@ -703,6 +704,11 @@ namespace Ryujinx.Tests.Cpu
[Values] bool q, [Values] bool q,
[Values] bool u) [Values] bool u)
{ {
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
{
Assert.Ignore("Unicorn on ARM64 crash while executing this test");
}
uint opcode = 0xf2000400u; // VSHL.S8 D0, D0, D0 uint opcode = 0xf2000400u; // VSHL.S8 D0, D0, D0
if (q) if (q)
{ {

View File

@@ -109,7 +109,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false); ExecuteOpcodes(runUnicorn: false);
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005)); Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
} }
[Test] [Test]
@@ -133,7 +133,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false); ExecuteOpcodes(runUnicorn: false);
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1005)); Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x5));
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false)); Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
} }
@@ -160,7 +160,7 @@ namespace Ryujinx.Tests.Cpu
ExecuteOpcodes(runUnicorn: false); ExecuteOpcodes(runUnicorn: false);
Assert.That(GetContext().GetX(0), Is.EqualTo(0x1007)); Assert.That(GetContext().GetX(0), Is.EqualTo(CodeBaseAddress + 0x7));
Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false)); Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
} }
} }

View File

@@ -268,6 +268,12 @@ namespace Ryujinx.Tests.Cpu
[Test] [Test]
public void TestRandomTestCases([ValueSource(nameof(RandomTestCases))] PrecomputedThumbTestCase test) public void TestRandomTestCases([ValueSource(nameof(RandomTestCases))] PrecomputedThumbTestCase test)
{ {
if (Size != 0x1000)
{
// TODO: Change it to depend on DataBaseAddress instead.
Assert.Ignore("This test currently only support 4KiB page size");
}
RunPrecomputedTestCase(test); RunPrecomputedTestCase(test);
} }