forked from Mirror/Ryujinx
Add some tests (#18)
* Add tests * Add some simple Alu instruction tests * travis: Run tests * CpuTest: Add TearDown
This commit is contained in:
parent
1df2c5ce7f
commit
1bfe6a9c22
10 changed files with 164 additions and 2 deletions
|
@ -6,3 +6,4 @@ dotnet: 2.0.0
|
||||||
script:
|
script:
|
||||||
- dotnet restore
|
- dotnet restore
|
||||||
- dotnet build
|
- dotnet build
|
||||||
|
- cd Ryujinx.Tests && dotnet test
|
||||||
|
|
73
Ryujinx.Tests/Cpu/CpuTest.cs
Normal file
73
Ryujinx.Tests/Cpu/CpuTest.cs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
using ChocolArm64;
|
||||||
|
using ChocolArm64.Memory;
|
||||||
|
using ChocolArm64.State;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Ryujinx.Tests.Cpu
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public partial class CpuTest
|
||||||
|
{
|
||||||
|
IntPtr Ram;
|
||||||
|
AMemoryAlloc Allocator;
|
||||||
|
AMemory Memory;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
|
||||||
|
Allocator = new AMemoryAlloc();
|
||||||
|
Memory = new AMemory(Ram, Allocator);
|
||||||
|
Memory.Manager.MapPhys(0x1000, 0x1000, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void Teardown()
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(Ram);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Execute(AThread Thread)
|
||||||
|
{
|
||||||
|
AutoResetEvent Wait = new AutoResetEvent(false);
|
||||||
|
Thread.Registers.Break += (sender, e) => Thread.StopExecution();
|
||||||
|
Thread.WorkFinished += (sender, e) => Wait.Set();
|
||||||
|
|
||||||
|
Wait.Reset();
|
||||||
|
Thread.Execute();
|
||||||
|
Wait.WaitOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ARegisters SingleOpcode(uint Opcode,
|
||||||
|
ulong X0 = 0, ulong X1 = 0, ulong X2 = 0,
|
||||||
|
AVec V0 = new AVec(), AVec V1 = new AVec(), AVec V2 = new AVec())
|
||||||
|
{
|
||||||
|
Memory.WriteUInt32(0x1000, Opcode);
|
||||||
|
Memory.WriteUInt32(0x1004, 0xD4200000); // BRK #0
|
||||||
|
Memory.WriteUInt32(0x1008, 0xD65F03C0); // RET
|
||||||
|
|
||||||
|
AThread Thread = new AThread(Memory, ThreadPriority.Normal, 0x1000);
|
||||||
|
Thread.Registers.X0 = X0;
|
||||||
|
Thread.Registers.X1 = X1;
|
||||||
|
Thread.Registers.X2 = X2;
|
||||||
|
Thread.Registers.V0 = V0;
|
||||||
|
Thread.Registers.V1 = V1;
|
||||||
|
Thread.Registers.V2 = V2;
|
||||||
|
Execute(Thread);
|
||||||
|
return Thread.Registers;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void SanityCheck()
|
||||||
|
{
|
||||||
|
uint Opcode = 0xD503201F; // NOP
|
||||||
|
Assert.AreEqual(SingleOpcode(Opcode, X0: 0).X0, 0);
|
||||||
|
Assert.AreEqual(SingleOpcode(Opcode, X0: 1).X0, 1);
|
||||||
|
Assert.AreEqual(SingleOpcode(Opcode, X0: 2).X0, 2);
|
||||||
|
Assert.AreEqual(SingleOpcode(Opcode, X0: 42).X0, 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
Ryujinx.Tests/Cpu/CpuTestAlu.cs
Normal file
65
Ryujinx.Tests/Cpu/CpuTestAlu.cs
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
using ChocolArm64.State;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace Ryujinx.Tests.Cpu
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public partial class CpuTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void Add()
|
||||||
|
{
|
||||||
|
// ADD X0, X1, X2
|
||||||
|
ARegisters Registers = SingleOpcode(0x8B020020, X1: 1, X2: 2);
|
||||||
|
Assert.AreEqual(3, Registers.X0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Ands()
|
||||||
|
{
|
||||||
|
// ANDS W0, W1, W2
|
||||||
|
uint Opcode = 0x6A020020;
|
||||||
|
var tests = new[]
|
||||||
|
{
|
||||||
|
new { W1 = 0xFFFFFFFFul, W2 = 0xFFFFFFFFul, Result = 0xFFFFFFFFul, Negative = true, Zero = false },
|
||||||
|
new { W1 = 0xFFFFFFFFul, W2 = 0x00000000ul, Result = 0x00000000ul, Negative = false, Zero = true },
|
||||||
|
new { W1 = 0x12345678ul, W2 = 0x7324A993ul, Result = 0x12240010ul, Negative = false, Zero = false },
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var test in tests)
|
||||||
|
{
|
||||||
|
ARegisters Registers = SingleOpcode(Opcode, X1: test.W1, X2: test.W2);
|
||||||
|
Assert.AreEqual(test.Result, Registers.X0);
|
||||||
|
Assert.AreEqual(test.Negative, Registers.Negative);
|
||||||
|
Assert.AreEqual(test.Zero, Registers.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void OrrBitmasks()
|
||||||
|
{
|
||||||
|
// ORR W0, WZR, #0x01010101
|
||||||
|
Assert.AreEqual(0x01010101, SingleOpcode(0x3200C3E0).X0);
|
||||||
|
// ORR W1, WZR, #0x00F000F0
|
||||||
|
Assert.AreEqual(0x00F000F0, SingleOpcode(0x320C8FE1).X1);
|
||||||
|
// ORR W2, WZR, #1
|
||||||
|
Assert.AreEqual(0x00000001, SingleOpcode(0x320003E2).X2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void RevX0X0()
|
||||||
|
{
|
||||||
|
// REV X0, X0
|
||||||
|
ARegisters Registers = SingleOpcode(0xDAC00C00, X0: 0xAABBCCDDEEFF1100);
|
||||||
|
Assert.AreEqual(0x0011FFEEDDCCBBAA, Registers.X0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void RevW1W1()
|
||||||
|
{
|
||||||
|
// REV W1, W1
|
||||||
|
ARegisters Registers = SingleOpcode(0x5AC00821, X1: 0x12345678);
|
||||||
|
Assert.AreEqual(0x78563412, Registers.X1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
Ryujinx.Tests/Ryujinx.Tests.csproj
Normal file
17
Ryujinx.Tests/Ryujinx.Tests.csproj
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170628-02" />
|
||||||
|
<PackageReference Include="NUnit" Version="3.9.0" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ryujinx\Ryujinx.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26730.8
|
VisualStudioVersion = 15.0.26730.8
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "Ryujinx.csproj", "{074045D4-3ED2-4711-9169-E385F2BFB5A0}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx", "Ryujinx\Ryujinx.csproj", "{074045D4-3ED2-4711-9169-E385F2BFB5A0}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Tests", "Ryujinx.Tests\Ryujinx.Tests.csproj", "{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -15,6 +17,10 @@ Global
|
||||||
{074045D4-3ED2-4711-9169-E385F2BFB5A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{074045D4-3ED2-4711-9169-E385F2BFB5A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{074045D4-3ED2-4711-9169-E385F2BFB5A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{074045D4-3ED2-4711-9169-E385F2BFB5A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{074045D4-3ED2-4711-9169-E385F2BFB5A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{074045D4-3ED2-4711-9169-E385F2BFB5A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Threading;
|
||||||
|
|
||||||
namespace ChocolArm64
|
namespace ChocolArm64
|
||||||
{
|
{
|
||||||
class AThread
|
public class AThread
|
||||||
{
|
{
|
||||||
public ARegisters Registers { get; private set; }
|
public ARegisters Registers { get; private set; }
|
||||||
public AMemory Memory { get; private set; }
|
public AMemory Memory { get; private set; }
|
||||||
|
|
Reference in a new issue