Просмотр исходного кода

Add some tests (#18)

* Add tests

* Add some simple Alu instruction tests

* travis: Run tests

* CpuTest: Add TearDown
Merry 8 лет назад
Родитель
Сommit
1bfe6a9c22

+ 1 - 0
.travis.yml

@@ -6,3 +6,4 @@ dotnet: 2.0.0
 script:
  - dotnet restore
  - dotnet build
+ - cd Ryujinx.Tests && dotnet test

+ 73 - 0
Ryujinx.Tests/Cpu/CpuTest.cs

@@ -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 - 0
Ryujinx.Tests/Cpu/CpuTestAlu.cs

@@ -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 - 0
Ryujinx.Tests/Ryujinx.Tests.csproj

@@ -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>

+ 7 - 1
Ryujinx.sln

@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 15
 VisualStudioVersion = 15.0.26730.8
 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
 Global
 	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}.Release|Any CPU.ActiveCfg = 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
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 1 - 1
Ryujinx/Cpu/AThread.cs

@@ -5,7 +5,7 @@ using System.Threading;
 
 namespace ChocolArm64
 {
-    class AThread
+    public class AThread
     {
         public ARegisters  Registers { get; private set; }
         public AMemory     Memory    { get; private set; }

+ 0 - 0
Ryujinx.conf → Ryujinx/Ryujinx.conf


+ 0 - 0
Ryujinx.csproj → Ryujinx/Ryujinx.csproj


+ 0 - 0
GLScreen.cs → Ryujinx/Ui/GLScreen.cs


+ 0 - 0
Program.cs → Ryujinx/Ui/Program.cs