[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>
This commit is contained in:
TSRBerry 2023-07-01 04:14:34 +02:00 committed by GitHub
parent 6e28a4dd13
commit e9848339dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 2263 additions and 1929 deletions

View file

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

View file

@ -1,14 +1,7 @@
using NUnit.Framework; using NUnit.Framework;
using Ryujinx.Audio.Renderer.Dsp; using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Server.Upsampler; using Ryujinx.Audio.Renderer.Server.Upsampler;
using System; 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 namespace Ryujinx.Tests.Audio.Renderer.Dsp
{ {
@ -17,7 +10,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
[Test] [Test]
public void TestUpsamplerConsistency() public void TestUpsamplerConsistency()
{ {
UpsamplerBufferState bufferState = new UpsamplerBufferState(); UpsamplerBufferState bufferState = new();
int inputBlockSize = 160; int inputBlockSize = 160;
int numInputSamples = 32000; int numInputSamples = 32000;
int numOutputSamples = 48000; int numOutputSamples = 48000;
@ -28,14 +21,14 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
for (int sample = 0; sample < inputBuffer.Length; sample++) for (int sample = 0; sample < inputBuffer.Length; sample++)
{ {
// 440 hz sine wave with amplitude = 0.5f at input sample rate // 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 inputIdx = 0;
int outputIdx = 0; int outputIdx = 0;
while (inputIdx + inputBlockSize < numInputSamples) 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( UpsamplerHelper.Upsample(
outputBuffer.AsSpan(outputIdx), outputBuffer.AsSpan(outputIdx),
inputBuffer.AsSpan(inputIdx), inputBuffer.AsSpan(inputIdx),
@ -52,11 +45,11 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
for (int sample = 0; sample < numOutputSamples; sample++) for (int sample = 0; sample < numOutputSamples; sample++)
{ {
// 440 hz sine wave with amplitude = 0.5f at output sample rate with an offset of 15 // 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 += 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 // Expect the output to be 98% similar to the expected resampled sine wave
Assert.IsTrue(sumDifference < 0.02f); 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] [Test]
public void TestCheckFeature() public void TestCheckFeature()
{ {
int latestRevision = BehaviourContext.BaseRevisionMagic + BehaviourContext.LastRevision; int latestRevision = BehaviourContext.BaseRevisionMagic + BehaviourContext.LastRevision;
int previousRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision - 1); int previousRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision - 1);
int invalidRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision + 1); int invalidRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision + 1);
@ -22,7 +22,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestsMemoryPoolForceMappingEnabled() public void TestsMemoryPoolForceMappingEnabled()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
@ -36,7 +36,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision1() public void TestRevision1()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
@ -62,7 +62,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision2() public void TestRevision2()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision2); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision2);
@ -88,7 +88,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision3() public void TestRevision3()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision3); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision3);
@ -114,7 +114,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision4() public void TestRevision4()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision4); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision4);
@ -140,7 +140,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision5() public void TestRevision5()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision5); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision5);
@ -166,7 +166,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision6() public void TestRevision6()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision6); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision6);
@ -192,7 +192,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision7() public void TestRevision7()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision7); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision7);
@ -218,7 +218,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision8() public void TestRevision8()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision8); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision8);
@ -244,7 +244,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision9() public void TestRevision9()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision9); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision9);
@ -270,7 +270,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestRevision10() public void TestRevision10()
{ {
BehaviourContext behaviourContext = new BehaviourContext(); BehaviourContext behaviourContext = new();
behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision10); behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision10);
@ -293,4 +293,4 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat()); Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
} }
} }
} }

View file

@ -15,13 +15,13 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestInitializeSystemPool() public void TestInitializeSystemPool()
{ {
PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true); PoolMapper poolMapper = new(DummyProcessHandle, true);
MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp); MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu); MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000; const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
const ulong CpuSize = 0x1000; const ulong CpuSize = 0x1000;
Assert.IsFalse(poolMapper.InitializeSystemPool(ref memoryPoolCpu, CpuAddress, CpuSize)); Assert.IsFalse(poolMapper.InitializeSystemPool(ref memoryPoolCpu, CpuAddress, CpuSize));
Assert.IsTrue(poolMapper.InitializeSystemPool(ref memoryPoolDsp, CpuAddress, CpuSize)); Assert.IsTrue(poolMapper.InitializeSystemPool(ref memoryPoolDsp, CpuAddress, CpuSize));
@ -34,7 +34,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestGetProcessHandle() public void TestGetProcessHandle()
{ {
PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true); PoolMapper poolMapper = new(DummyProcessHandle, true);
MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp); MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu); MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
@ -45,13 +45,13 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test] [Test]
public void TestMappings() public void TestMappings()
{ {
PoolMapper poolMapper = new PoolMapper(DummyProcessHandle, true); PoolMapper poolMapper = new(DummyProcessHandle, true);
MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp); MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu); MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000; const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
const ulong CpuSize = 0x1000; const ulong CpuSize = 0x1000;
memoryPoolDsp.SetCpuAddress(CpuAddress, CpuSize); memoryPoolDsp.SetCpuAddress(CpuAddress, CpuSize);
memoryPoolCpu.SetCpuAddress(CpuAddress, CpuSize); memoryPoolCpu.SetCpuAddress(CpuAddress, CpuSize);
@ -72,10 +72,10 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
{ {
const CpuAddress CpuAddress = 0x20000; const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
const ulong CpuSize = 0x1000; const ulong CpuSize = 0x1000;
const int MemoryPoolStateArraySize = 0x10; const int MemoryPoolStateArraySize = 0x10;
const CpuAddress CpuAddressRegionEnding = CpuAddress * MemoryPoolStateArraySize; const CpuAddress CpuAddressRegionEnding = CpuAddress * MemoryPoolStateArraySize;
MemoryPoolState[] memoryPoolStateArray = new MemoryPoolState[MemoryPoolStateArraySize]; MemoryPoolState[] memoryPoolStateArray = new MemoryPoolState[MemoryPoolStateArraySize];
@ -85,13 +85,12 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
memoryPoolStateArray[i].SetCpuAddress(CpuAddress + (ulong)i * CpuSize, CpuSize); memoryPoolStateArray[i].SetCpuAddress(CpuAddress + (ulong)i * CpuSize, CpuSize);
} }
ErrorInfo errorInfo;
AddressInfo addressInfo = AddressInfo.Create(); 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(ResultCode.InvalidAddressInfo, errorInfo.ErrorCode);
Assert.AreEqual(0, errorInfo.ExtraErrorInfo); Assert.AreEqual(0, errorInfo.ExtraErrorInfo);
@ -105,7 +104,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
poolMapper = new PoolMapper(DummyProcessHandle, false); 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; 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 = 0xffff8fffffff8fff, Valid = true, ImmN = 0, ImmS = 0x1c, ImmR = 17 },
new() { Value = 0x000000000ffff800, Valid = true, ImmN = 1, ImmS = 0x10, ImmR = 53 }, new() { Value = 0x000000000ffff800, Valid = true, ImmN = 1, ImmS = 0x10, ImmR = 53 },
}; };
[Test] [Test]
public void BitImmTests([ValueSource(nameof(TestCases))] TestCase test) public void BitImmTests([ValueSource(nameof(TestCases))] TestCase test)
{ {
@ -43,4 +43,4 @@ namespace Ryujinx.Tests.Cpu
Assert.That(immR, Is.EqualTo(test.ImmR)); Assert.That(immR, Is.EqualTo(test.ImmR));
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -26,7 +26,7 @@ namespace Ryujinx.Tests.Cpu
} }
} }
#region "ValueSource (CRC32)" #region "ValueSource (CRC32)"
private static CrcTest[] _CRC32_Test_Values_() private static CrcTest[] _CRC32_Test_Values_()
{ {
// Created with http://www.sunshine2k.de/coding/javascript/crc/crc_js.html, with: // 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, 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, 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, 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] [Test, Combinatorial]
public void Crc32_b_h_w_x([Values(0u)] uint rd, public void Crc32_b_h_w_x([Values(0u)] uint rd,
@ -304,4 +304,4 @@ namespace Ryujinx.Tests.Cpu
} }
#endif #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_() private static CrcTest32[] _CRC32_Test_Values_()
{ {
// Created with http://www.sunshine2k.de/coding/javascript/crc/crc_js.html, with: // 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, 0x7f_ff_ff_ffu, true, 0x00ffffff, 0x0000ffff, 0x82f63b78),
new CrcTest32(0xffffffffu, 0x80_00_00_00u, true, 0xad82acae, 0x0e9e882d, 0x356e8f40), 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, 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] [Test, Combinatorial]
public void Crc32_Crc32c_b_h_w([Values(0u)] uint rd, public void Crc32_Crc32c_b_h_w([Values(0u)] uint rd,

View file

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

View file

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

View file

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

View file

@ -9,7 +9,7 @@ namespace Ryujinx.Tests.Cpu
{ {
#if AluRs32 #if AluRs32
#region "ValueSource (Opcodes)" #region "ValueSource (Opcodes)"
private static uint[] _Add_Adds_Rsb_Rsbs_() private static uint[] _Add_Adds_Rsb_Rsbs_()
{ {
return new[] return new[]
@ -17,7 +17,7 @@ namespace Ryujinx.Tests.Cpu
0xe0800000u, // ADD R0, R0, R0, LSL #0 0xe0800000u, // ADD R0, R0, R0, LSL #0
0xe0900000u, // ADDS R0, R0, R0, LSL #0 0xe0900000u, // ADDS R0, R0, R0, LSL #0
0xe0600000u, // RSB 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 0xe0e00000u, // RSC R0, R0, R0
0xe0f00000u, // RSCS R0, R0, R0 0xe0f00000u, // RSCS R0, R0, R0
0xe0c00000u, // SBC R0, R0, R0 0xe0c00000u, // SBC R0, R0, R0
0xe0d00000u // SBCS R0, R0, R0 0xe0d00000u, // SBCS R0, R0, R0
}; };
} }
#endregion #endregion
[Test, Pairwise] [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(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn, [Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm, [Values(2u, 13u)] uint rm,
@ -57,7 +57,7 @@ namespace Ryujinx.Tests.Cpu
} }
[Test, Pairwise] [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(0u, 13u)] uint rd,
[Values(1u, 13u)] uint rn, [Values(1u, 13u)] uint rn,
[Values(2u, 13u)] uint rm, [Values(2u, 13u)] uint rm,
@ -79,4 +79,4 @@ namespace Ryujinx.Tests.Cpu
} }
#endif #endif
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -10,21 +10,25 @@ namespace Ryujinx.Tests.Cpu
{ {
#if SimdRegElem #if SimdRegElem
#region "ValueSource (Types)" #region "ValueSource (Types)"
private static ulong[] _2S_() private static ulong[] _2S_()
{ {
return new[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul, return new[] {
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul }; 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
} }
private static ulong[] _4H_() private static ulong[] _4H_()
{ {
return new[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul, return new[] {
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul }; 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
} }
#endregion #endregion
#region "ValueSource (Opcodes)" #region "ValueSource (Opcodes)"
private static uint[] _Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_() private static uint[] _Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_()
{ {
return new[] return new[]
@ -33,7 +37,7 @@ namespace Ryujinx.Tests.Cpu
0x2F404000u, // MLS V0.4H, V0.4H, V0.H[0] 0x2F404000u, // MLS V0.4H, V0.4H, V0.H[0]
0x0F408000u, // MUL 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] 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] 0x2F804000u, // MLS V0.2S, V0.2S, V0.S[0]
0x0F808000u, // MUL 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] 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] 0x0F40A000u, // SMULL V0.4S, V0.4H, V0.H[0]
0x2F402000u, // UMLAL 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] 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] 0x0F80A000u, // SMULL V0.2D, V0.2S, V0.S[0]
0x2F802000u, // UMLAL 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] 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] [Test, Pairwise]
public void Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H([ValueSource(nameof(_Mla_Mls_Mul_Sqdmulh_Sqrdmulh_Ve_4H_8H_))] uint opcodes, 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(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm, [Values(2u, 0u)] uint rm,
[ValueSource(nameof(_4H_))] ulong z, [ValueSource(nameof(_4H_))] ulong z,
@ -134,7 +138,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S([ValueSource(nameof(_SU_Mlal_Mlsl_Mull_Ve_4H4S_8H4S_))] uint opcodes, 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(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm, [Values(2u, 0u)] uint rm,
[ValueSource(nameof(_4H_))] ulong z, [ValueSource(nameof(_4H_))] ulong z,
@ -162,7 +166,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D([ValueSource(nameof(_SU_Mlal_Mlsl_Mull_Ve_2S2D_4S2D_))] uint opcodes, 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(1u, 0u)] uint rn,
[Values(2u, 0u)] uint rm, [Values(2u, 0u)] uint rm,
[ValueSource(nameof(_2S_))] ulong z, [ValueSource(nameof(_2S_))] ulong z,
@ -188,4 +192,4 @@ namespace Ryujinx.Tests.Cpu
} }
#endif #endif
} }
} }

View file

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

View file

@ -12,41 +12,53 @@ namespace Ryujinx.Tests.Cpu
{ {
#if SimdShImm #if SimdShImm
#region "ValueSource (Types)" #region "ValueSource (Types)"
private static ulong[] _1D_() private static ulong[] _1D_()
{ {
return new[] { 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul, return new[] {
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul }; 0x0000000000000000ul, 0x7FFFFFFFFFFFFFFFul,
0x8000000000000000ul, 0xFFFFFFFFFFFFFFFFul,
};
} }
private static ulong[] _1H_() private static ulong[] _1H_()
{ {
return new[] { 0x0000000000000000ul, 0x0000000000007FFFul, return new[] {
0x0000000000008000ul, 0x000000000000FFFFul }; 0x0000000000000000ul, 0x0000000000007FFFul,
0x0000000000008000ul, 0x000000000000FFFFul,
};
} }
private static ulong[] _1S_() private static ulong[] _1S_()
{ {
return new[] { 0x0000000000000000ul, 0x000000007FFFFFFFul, return new[] {
0x0000000080000000ul, 0x00000000FFFFFFFFul }; 0x0000000000000000ul, 0x000000007FFFFFFFul,
0x0000000080000000ul, 0x00000000FFFFFFFFul,
};
} }
private static ulong[] _2S_() private static ulong[] _2S_()
{ {
return new[] { 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul, return new[] {
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul }; 0x0000000000000000ul, 0x7FFFFFFF7FFFFFFFul,
0x8000000080000000ul, 0xFFFFFFFFFFFFFFFFul,
};
} }
private static ulong[] _4H_() private static ulong[] _4H_()
{ {
return new[] { 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul, return new[] {
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul }; 0x0000000000000000ul, 0x7FFF7FFF7FFF7FFFul,
0x8000800080008000ul, 0xFFFFFFFFFFFFFFFFul,
};
} }
private static ulong[] _8B_() private static ulong[] _8B_()
{ {
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful, return new[] {
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul }; 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul,
};
} }
private static IEnumerable<ulong> _2S_F_W_() private static IEnumerable<ulong> _2S_F_W_()
@ -73,19 +85,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x007FFFFF007FFFFFul; // +Max Subnormal yield return 0x007FFFFF007FFFFFul; // +Max Subnormal
yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon) yield return 0x0000000100000001ul; // +Min Subnormal (float.Epsilon)
if (!NoZeros) if (!_noZeros)
{ {
yield return 0x8000000080000000ul; // -Zero yield return 0x8000000080000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero yield return 0x0000000000000000ul; // +Zero
} }
if (!NoInfs) if (!_noInfs)
{ {
yield return 0xFF800000FF800000ul; // -Infinity yield return 0xFF800000FF800000ul; // -Infinity
yield return 0x7F8000007F800000ul; // +Infinity yield return 0x7F8000007F800000ul; // +Infinity
} }
if (!NoNaNs) if (!_noNaNs)
{ {
yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN) yield return 0xFFC00000FFC00000ul; // -QNaN (all zeros payload) (float.NaN)
yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload) yield return 0xFFBFFFFFFFBFFFFFul; // -SNaN (all ones payload)
@ -133,19 +145,19 @@ namespace Ryujinx.Tests.Cpu
yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal yield return 0x000FFFFFFFFFFFFFul; // +Max Subnormal
yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon) yield return 0x0000000000000001ul; // +Min Subnormal (double.Epsilon)
if (!NoZeros) if (!_noZeros)
{ {
yield return 0x8000000000000000ul; // -Zero yield return 0x8000000000000000ul; // -Zero
yield return 0x0000000000000000ul; // +Zero yield return 0x0000000000000000ul; // +Zero
} }
if (!NoInfs) if (!_noInfs)
{ {
yield return 0xFFF0000000000000ul; // -Infinity yield return 0xFFF0000000000000ul; // -Infinity
yield return 0x7FF0000000000000ul; // +Infinity yield return 0x7FF0000000000000ul; // +Infinity
} }
if (!NoNaNs) if (!_noNaNs)
{ {
yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN) yield return 0xFFF8000000000000ul; // -QNaN (all zeros payload) (double.NaN)
yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload) yield return 0xFFF7FFFFFFFFFFFFul; // -SNaN (all ones payload)
@ -170,15 +182,15 @@ namespace Ryujinx.Tests.Cpu
yield return rnd4; yield return rnd4;
} }
} }
#endregion #endregion
#region "ValueSource (Opcodes)" #region "ValueSource (Opcodes)"
private static uint[] _F_Cvt_Z_SU_V_Fixed_2S_4S_() private static uint[] _F_Cvt_Z_SU_V_Fixed_2S_4S_()
{ {
return new[] return new[]
{ {
0x0F20FC00u, // FCVTZS V0.2S, V0.2S, #32 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[] return new[]
{ {
0x4F40FC00u, // FCVTZS V0.2D, V0.2D, #64 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[] return new[]
{ {
0x5F20E420u, // SCVTF S0, S1, #32 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[] return new[]
{ {
0x5F40E420u, // SCVTF D0, D1, #64 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[] return new[]
{ {
0x0F20E400u, // SCVTF V0.2S, V0.2S, #32 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[] return new[]
{ {
0x4F40E400u, // SCVTF V0.2D, V0.2D, #64 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[] return new[]
{ {
0x5F405400u, // SHL D0, D0, #0 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[] return new[]
{ {
0x0F085400u, // SHL V0.8B, V0.8B, #0 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[] return new[]
{ {
0x0F105400u, // SHL V0.4H, V0.4H, #0 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[] return new[]
{ {
0x0F205400u, // SHL V0.2S, V0.2S, #0 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[] return new[]
{ {
0x4F405400u, // SHL V0.2D, V0.2D, #0 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[] return new[]
{ {
0x0F08A400u, // SSHLL V0.8H, V0.8B, #0 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[] return new[]
{ {
0x0F10A400u, // SSHLL V0.4S, V0.4H, #0 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[] return new[]
{ {
0x0F20A400u, // SSHLL V0.2D, V0.2S, #0 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 0x7F402400u, // URSHR D0, D0, #64
0x7F403400u, // URSRA D0, D0, #64 0x7F403400u, // URSRA D0, D0, #64
0x7F400400u, // USHR 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 0x2F082400u, // URSHR V0.8B, V0.8B, #8
0x2F083400u, // URSRA V0.8B, V0.8B, #8 0x2F083400u, // URSRA V0.8B, V0.8B, #8
0x2F080400u, // USHR 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 0x2F102400u, // URSHR V0.4H, V0.4H, #16
0x2F103400u, // URSRA V0.4H, V0.4H, #16 0x2F103400u, // URSRA V0.4H, V0.4H, #16
0x2F100400u, // USHR 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 0x2F202400u, // URSHR V0.2S, V0.2S, #32
0x2F203400u, // URSRA V0.2S, V0.2S, #32 0x2F203400u, // URSRA V0.2S, V0.2S, #32
0x2F200400u, // USHR 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 0x6F402400u, // URSHR V0.2D, V0.2D, #64
0x6F403400u, // URSRA V0.2D, V0.2D, #64 0x6F403400u, // URSRA V0.2D, V0.2D, #64
0x6F400400u, // USHR 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[] return new[]
{ {
0x0F088C00u, // RSHRN V0.8B, V0.8H, #8 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[] return new[]
{ {
0x0F108C00u, // RSHRN V0.4H, V0.4S, #16 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[] return new[]
{ {
0x0F208C00u, // RSHRN V0.2S, V0.2D, #32 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 0x7F088C00u, // SQRSHRUN B0, H0, #8
0x5F089400u, // SQSHRN B0, H0, #8 0x5F089400u, // SQSHRN B0, H0, #8
0x7F089400u, // UQSHRN 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 0x7F108C00u, // SQRSHRUN H0, S0, #16
0x5F109400u, // SQSHRN H0, S0, #16 0x5F109400u, // SQSHRN H0, S0, #16
0x7F109400u, // UQSHRN 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 0x7F208C00u, // SQRSHRUN S0, D0, #32
0x5F209400u, // SQSHRN S0, D0, #32 0x5F209400u, // SQSHRN S0, D0, #32
0x7F209400u, // UQSHRN 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 0x2F088C00u, // SQRSHRUN V0.8B, V0.8H, #8
0x0F089400u, // SQSHRN V0.8B, V0.8H, #8 0x0F089400u, // SQSHRN V0.8B, V0.8H, #8
0x2F089400u, // UQSHRN 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 0x2F108C00u, // SQRSHRUN V0.4H, V0.4S, #16
0x0F109400u, // SQSHRN V0.4H, V0.4S, #16 0x0F109400u, // SQSHRN V0.4H, V0.4S, #16
0x2F109400u, // UQSHRN 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 0x2F208C00u, // SQRSHRUN V0.2S, V0.2D, #32
0x0F209400u, // SQSHRN V0.2S, V0.2D, #32 0x0F209400u, // SQSHRN V0.2S, V0.2D, #32
0x2F209400u, // UQSHRN 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 _noZeros = false;
private static readonly bool NoInfs = false; private static readonly bool _noInfs = false;
private static readonly bool NoNaNs = 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, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_F_W_))] ulong z, [ValueSource(nameof(_2S_F_W_))] ulong z,
[ValueSource(nameof(_2S_F_W_))] ulong a, [ValueSource(nameof(_2S_F_W_))] ulong a,
@ -514,9 +527,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(); 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, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_F_X_))] ulong z, [ValueSource(nameof(_1D_F_X_))] ulong z,
[ValueSource(nameof(_1D_F_X_))] ulong a, [ValueSource(nameof(_1D_F_X_))] ulong a,
@ -535,7 +549,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(); 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, public void SU_Cvt_F_S_Fixed_S([ValueSource(nameof(_SU_Cvt_F_S_Fixed_S_))] uint opcodes,
[ValueSource(nameof(_1S_))] ulong a, [ValueSource(nameof(_1S_))] ulong a,
[Values(1u, 32u)] uint fBits) [Values(1u, 32u)] uint fBits)
@ -553,7 +568,8 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(); 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, public void SU_Cvt_F_S_Fixed_D([ValueSource(nameof(_SU_Cvt_F_S_Fixed_D_))] uint opcodes,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
[Values(1u, 64u)] uint fBits) [Values(1u, 64u)] uint fBits)
@ -571,9 +587,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(); 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, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z, [ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a, [ValueSource(nameof(_2S_))] ulong a,
@ -594,9 +611,10 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn(); 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, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -617,7 +635,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Shl_Sli_S_D([ValueSource(nameof(_Shl_Sli_S_D_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -638,7 +656,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Shl_Sli_V_8B_16B([ValueSource(nameof(_Shl_Sli_V_8B_16B_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z, [ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a, [ValueSource(nameof(_8B_))] ulong a,
@ -661,7 +679,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Shl_Sli_V_4H_8H([ValueSource(nameof(_Shl_Sli_V_4H_8H_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z, [ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a, [ValueSource(nameof(_4H_))] ulong a,
@ -684,7 +702,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Shl_Sli_V_2S_4S([ValueSource(nameof(_Shl_Sli_V_2S_4S_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z, [ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a, [ValueSource(nameof(_2S_))] ulong a,
@ -707,7 +725,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Shl_Sli_V_2D([ValueSource(nameof(_Shl_Sli_V_2D_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -728,7 +746,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void SU_Shll_V_8B8H_16B8H([ValueSource(nameof(_SU_Shll_V_8B8H_16B8H_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z, [ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a, [ValueSource(nameof(_8B_))] ulong a,
@ -751,7 +769,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void SU_Shll_V_4H4S_8H4S([ValueSource(nameof(_SU_Shll_V_4H4S_8H4S_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z, [ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a, [ValueSource(nameof(_4H_))] ulong a,
@ -774,7 +792,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void SU_Shll_V_2S2D_4S2D([ValueSource(nameof(_SU_Shll_V_2S2D_4S2D_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z, [ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a, [ValueSource(nameof(_2S_))] ulong a,
@ -797,7 +815,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImm_Sri_S_D([ValueSource(nameof(_ShrImm_Sri_S_D_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -818,7 +836,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImm_Sri_V_8B_16B([ValueSource(nameof(_ShrImm_Sri_V_8B_16B_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_8B_))] ulong z, [ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong a, [ValueSource(nameof(_8B_))] ulong a,
@ -841,7 +859,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImm_Sri_V_4H_8H([ValueSource(nameof(_ShrImm_Sri_V_4H_8H_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z, [ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a, [ValueSource(nameof(_4H_))] ulong a,
@ -864,7 +882,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImm_Sri_V_2S_4S([ValueSource(nameof(_ShrImm_Sri_V_2S_4S_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z, [ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a, [ValueSource(nameof(_2S_))] ulong a,
@ -887,7 +905,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImm_Sri_V_2D([ValueSource(nameof(_ShrImm_Sri_V_2D_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -908,7 +926,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmNarrow_V_8H8B_8H16B([ValueSource(nameof(_ShrImmNarrow_V_8H8B_8H16B_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z, [ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a, [ValueSource(nameof(_4H_))] ulong a,
@ -931,7 +949,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmNarrow_V_4S4H_4S8H([ValueSource(nameof(_ShrImmNarrow_V_4S4H_4S8H_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z, [ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a, [ValueSource(nameof(_2S_))] ulong a,
@ -954,7 +972,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmNarrow_V_2D2S_2D4S([ValueSource(nameof(_ShrImmNarrow_V_2D2S_2D4S_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -977,7 +995,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmSaturatingNarrow_S_HB([ValueSource(nameof(_ShrImmSaturatingNarrow_S_HB_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1H_))] ulong z, [ValueSource(nameof(_1H_))] ulong z,
[ValueSource(nameof(_1H_))] ulong a, [ValueSource(nameof(_1H_))] ulong a,
@ -998,7 +1016,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmSaturatingNarrow_S_SH([ValueSource(nameof(_ShrImmSaturatingNarrow_S_SH_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1S_))] ulong z, [ValueSource(nameof(_1S_))] ulong z,
[ValueSource(nameof(_1S_))] ulong a, [ValueSource(nameof(_1S_))] ulong a,
@ -1019,7 +1037,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmSaturatingNarrow_S_DS([ValueSource(nameof(_ShrImmSaturatingNarrow_S_DS_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -1040,7 +1058,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmSaturatingNarrow_V_8H8B_8H16B([ValueSource(nameof(_ShrImmSaturatingNarrow_V_8H8B_8H16B_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_4H_))] ulong z, [ValueSource(nameof(_4H_))] ulong z,
[ValueSource(nameof(_4H_))] ulong a, [ValueSource(nameof(_4H_))] ulong a,
@ -1063,7 +1081,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmSaturatingNarrow_V_4S4H_4S8H([ValueSource(nameof(_ShrImmSaturatingNarrow_V_4S4H_4S8H_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_2S_))] ulong z, [ValueSource(nameof(_2S_))] ulong z,
[ValueSource(nameof(_2S_))] ulong a, [ValueSource(nameof(_2S_))] ulong a,
@ -1086,7 +1104,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void ShrImmSaturatingNarrow_V_2D2S_2D4S([ValueSource(nameof(_ShrImmSaturatingNarrow_V_2D2S_2D4S_))] uint opcodes, 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, [Values(1u, 0u)] uint rn,
[ValueSource(nameof(_1D_))] ulong z, [ValueSource(nameof(_1D_))] ulong z,
[ValueSource(nameof(_1D_))] ulong a, [ValueSource(nameof(_1D_))] ulong a,
@ -1108,4 +1126,4 @@ namespace Ryujinx.Tests.Cpu
} }
#endif #endif
} }
} }

View file

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

View file

@ -11,19 +11,19 @@ namespace Ryujinx.Tests.Cpu
{ {
#if SimdTbl #if SimdTbl
#region "Helper methods" #region "Helper methods"
private static ulong GenIdxsForTbls(int regs) private static ulong GenIdxsForTbls(int regs)
{ {
const byte IdxInRngMin = 0; const byte IdxInRngMin = 0;
byte idxInRngMax = (byte)((16 * regs) - 1); byte idxInRngMax = (byte)((16 * regs) - 1);
byte idxOutRngMin = (byte) (16 * regs); byte idxOutRngMin = (byte)(16 * regs);
const byte IdxOutRngMax = 255; const byte IdxOutRngMax = 255;
ulong idxs = 0ul; ulong idxs = 0ul;
for (int cnt = 1; cnt <= 8; cnt++) 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 idxOutRng = TestContext.CurrentContext.Random.NextByte(idxOutRngMin, IdxOutRngMax);
ulong idx = TestContext.CurrentContext.Random.NextBool() ? idxInRng : idxOutRng; ulong idx = TestContext.CurrentContext.Random.NextBool() ? idxInRng : idxOutRng;
@ -33,13 +33,15 @@ namespace Ryujinx.Tests.Cpu
return idxs; return idxs;
} }
#endregion #endregion
#region "ValueSource (Types)" #region "ValueSource (Types)"
private static ulong[] _8B_() private static ulong[] _8B_()
{ {
return new[] { 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful, return new[] {
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul }; 0x0000000000000000ul, 0x7F7F7F7F7F7F7F7Ful,
0x8080808080808080ul, 0xFFFFFFFFFFFFFFFFul,
};
} }
private static IEnumerable<ulong> _GenIdxsForTbl1_() private static IEnumerable<ulong> _GenIdxsForTbl1_()
@ -93,15 +95,15 @@ namespace Ryujinx.Tests.Cpu
yield return GenIdxsForTbls(regs: 4); yield return GenIdxsForTbls(regs: 4);
} }
} }
#endregion #endregion
#region "ValueSource (Opcodes)" #region "ValueSource (Opcodes)"
private static uint[] _SingleRegisterTable_V_8B_16B_() private static uint[] _SingleRegisterTable_V_8B_16B_()
{ {
return new[] return new[]
{ {
0x0E000000u, // TBL V0.8B, { V0.16B }, V0.8B 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[] return new[]
{ {
0x0E002000u, // TBL V0.8B, { V0.16B, V1.16B }, V0.8B 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[] return new[]
{ {
0x0E004000u, // TBL V0.8B, { V0.16B, V1.16B, V2.16B }, V0.8B 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[] return new[]
{ {
0x0E006000u, // TBL V0.8B, { V0.16B, V1.16B, V2.16B, V3.16B }, V0.8B 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; private const int RndCntIdxs = 2;
@ -184,7 +186,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Mod_TwoRegisterTable_V_8B_16B([ValueSource(nameof(_TwoRegisterTable_V_8B_16B_))] uint opcodes, public void Mod_TwoRegisterTable_V_8B_16B([ValueSource(nameof(_TwoRegisterTable_V_8B_16B_))] uint opcodes,
[Values(30u, 1u)] uint rd, [Values(30u, 1u)] uint rd,
[Values(31u)] uint rn, [Values(31u)] uint rn,
[Values(1u, 30u)] uint rm, [Values(1u, 30u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z, [ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong table0, [ValueSource(nameof(_8B_))] ulong table0,
@ -197,8 +199,8 @@ namespace Ryujinx.Tests.Cpu
V128 v30 = MakeVectorE0E1(z, z); V128 v30 = MakeVectorE0E1(z, z);
V128 v31 = MakeVectorE0E1(table0, table0); V128 v31 = MakeVectorE0E1(table0, table0);
V128 v0 = MakeVectorE0E1(table1, table1); V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(indexes, indexes); V128 v1 = MakeVectorE0E1(indexes, indexes);
SingleOpcode(opcodes, v0: v0, v1: v1, v30: v30, v31: v31); SingleOpcode(opcodes, v0: v0, v1: v1, v30: v30, v31: v31);
@ -234,7 +236,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Mod_ThreeRegisterTable_V_8B_16B([ValueSource(nameof(_ThreeRegisterTable_V_8B_16B_))] uint opcodes, public void Mod_ThreeRegisterTable_V_8B_16B([ValueSource(nameof(_ThreeRegisterTable_V_8B_16B_))] uint opcodes,
[Values(30u, 2u)] uint rd, [Values(30u, 2u)] uint rd,
[Values(31u)] uint rn, [Values(31u)] uint rn,
[Values(2u, 30u)] uint rm, [Values(2u, 30u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z, [ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong table0, [ValueSource(nameof(_8B_))] ulong table0,
@ -248,9 +250,9 @@ namespace Ryujinx.Tests.Cpu
V128 v30 = MakeVectorE0E1(z, z); V128 v30 = MakeVectorE0E1(z, z);
V128 v31 = MakeVectorE0E1(table0, table0); V128 v31 = MakeVectorE0E1(table0, table0);
V128 v0 = MakeVectorE0E1(table1, table1); V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(table2, table2); V128 v1 = MakeVectorE0E1(table2, table2);
V128 v2 = MakeVectorE0E1(indexes, indexes); V128 v2 = MakeVectorE0E1(indexes, indexes);
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v30: v30, v31: v31); SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v30: v30, v31: v31);
@ -288,7 +290,7 @@ namespace Ryujinx.Tests.Cpu
[Test, Pairwise] [Test, Pairwise]
public void Mod_FourRegisterTable_V_8B_16B([ValueSource(nameof(_FourRegisterTable_V_8B_16B_))] uint opcodes, public void Mod_FourRegisterTable_V_8B_16B([ValueSource(nameof(_FourRegisterTable_V_8B_16B_))] uint opcodes,
[Values(30u, 3u)] uint rd, [Values(30u, 3u)] uint rd,
[Values(31u)] uint rn, [Values(31u)] uint rn,
[Values(3u, 30u)] uint rm, [Values(3u, 30u)] uint rm,
[ValueSource(nameof(_8B_))] ulong z, [ValueSource(nameof(_8B_))] ulong z,
[ValueSource(nameof(_8B_))] ulong table0, [ValueSource(nameof(_8B_))] ulong table0,
@ -303,10 +305,10 @@ namespace Ryujinx.Tests.Cpu
V128 v30 = MakeVectorE0E1(z, z); V128 v30 = MakeVectorE0E1(z, z);
V128 v31 = MakeVectorE0E1(table0, table0); V128 v31 = MakeVectorE0E1(table0, table0);
V128 v0 = MakeVectorE0E1(table1, table1); V128 v0 = MakeVectorE0E1(table1, table1);
V128 v1 = MakeVectorE0E1(table2, table2); V128 v1 = MakeVectorE0E1(table2, table2);
V128 v2 = MakeVectorE0E1(table3, table3); V128 v2 = MakeVectorE0E1(table3, table3);
V128 v3 = MakeVectorE0E1(indexes, indexes); V128 v3 = MakeVectorE0E1(indexes, indexes);
SingleOpcode(opcodes, v0: v0, v1: v1, v2: v2, v3: v3, v30: v30, v31: v31); 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 #if System
#region "ValueSource (Types)" #region "ValueSource (Types)"
private static IEnumerable<ulong> _GenNzcv_() private static IEnumerable<ulong> _GenNzcv_()
{ {
yield return 0x0000000000000000ul; yield return 0x0000000000000000ul;
@ -33,23 +33,23 @@ namespace Ryujinx.Tests.Cpu
yield return rnd; yield return rnd;
} }
#endregion #endregion
#region "ValueSource (Opcodes)" #region "ValueSource (Opcodes)"
private static uint[] _MrsMsr_Nzcv_() private static uint[] _MrsMsr_Nzcv_()
{ {
return new[] return new[]
{ {
0xD53B4200u, // MRS X0, NZCV 0xD53B4200u, // MRS X0, NZCV
0xD51B4200u // MSR NZCV, X0 0xD51B4200u, // MSR NZCV, X0
}; };
} }
#endregion #endregion
[Test, Pairwise] [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, [Values(0u, 1u, 31u)] uint rt,
[ValueSource("_GenNzcv_")] ulong xt) [ValueSource(nameof(_GenNzcv_))] ulong xt)
{ {
opcodes |= (rt & 31) << 0; opcodes |= (rt & 31) << 0;
@ -66,4 +66,4 @@ namespace Ryujinx.Tests.Cpu
} }
#endif #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)); Assert.That(GetContext().GetPstateFlag(PState.TFlag), Is.EqualTo(false));
} }
} }
} }

View file

@ -1,4 +1,5 @@
using NUnit.Framework; using NUnit.Framework;
using System;
namespace Ryujinx.Tests.Cpu namespace Ryujinx.Tests.Cpu
{ {
@ -14,70 +15,70 @@ namespace Ryujinx.Tests.Cpu
public static readonly PrecomputedMemoryThumbTestCase[] ImmTestCases = public static readonly PrecomputedMemoryThumbTestCase[] ImmTestCases =
{ {
// STRB (imm8) // STRB (imm8)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf80c, 0x1b2f, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x21fe, Value: 0xbbfe) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf80a, 0x2f81, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x26f0, Value: 0x2600) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf803, 0x6968, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2dac, Value: 0x2dc9) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf804, 0x89ad, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2412, Value: 0xca12) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf80d, 0xa9fe, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2d9c, Value: 0x0a9c) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf80d, 0x3c46, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2b76, Value: 0xcc76) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf801, 0x6c56, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x24da, Value: 0x2473) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf809, 0xcc76, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2c8c, Value: 0xee8c) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf808, 0x1c8d, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2e40, Value: 0x2e78) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf80b, 0xbc26, 0x4770, 0xe7fe }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2b86, Value: 0x2bac) },
}, },
// STRB (imm12) // STRB (imm12)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf887, 0x67c2, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x27c2, Value: 0x2700) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf883, 0x9fda, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2fda, Value: 0x2f00) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf889, 0xd200, 0x4770, 0xe7fe }, 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 }, 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 }, 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 }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2c5a, Value: 0x005a) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf887, 0x9fe2, 0x4770, 0xe7fe }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2fe2, Value: 0x2f00) },
}, },
// STRH (imm8) // STRH (imm8)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf826, 0x0b0a, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2620, Value: 0x25a2) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf827, 0xcf61, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2a4c, Value: 0x2e29) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf821, 0x9b00, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2514, Value: 0x2398) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf82c, 0xa927, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x29a0, Value: 0x4aa0), (Address: 0x29a2, Value: 0x2927) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf824, 0xcfe4, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2526, Value: 0x2d1c) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf820, 0x1c3d, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x21ea, Value: 0x2b29) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf826, 0x1cdf, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x265a, Value: 0xa15a), (Address: 0x265c, Value: 0x2629) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf82b, 0x3c66, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2798, Value: 0xdf98), (Address: 0x279a, Value: 0x2721) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf822, 0x3c06, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2afa, Value: 0x2207) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf824, 0xac84, 0x4770, 0xe7fe }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2186, Value: 0xf886), (Address: 0x2188, Value: 0x2128) },
}, },
// STRH (imm12) // STRH (imm12)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8a5, 0x59d4, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x29d4, Value: 0x2000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8ac, 0xc533, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2532, Value: 0x0032), (Address: 0x2534, Value: 0x2520) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8a3, 0xb559, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2558, Value: 0x0058), (Address: 0x255a, Value: 0x2520) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8a5, 0xdb3a, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2b3a, Value: 0x2000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8a9, 0x02cc, 0x4770, 0xe7fe }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x22cc, Value: 0x2000) },
}, },
// STR (imm8) // STR (imm8)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf846, 0x1fb4, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, 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 }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x27cc, Value: 0x23ac), (Address: 0x27ce, Value: 0x0000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf847, 0x09c2, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x211c, Value: 0x248b), (Address: 0x211e, Value: 0x0000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf84d, 0x7f23, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2c56, Value: 0x2b63), (Address: 0x2c58, Value: 0x0000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf843, 0x9d24, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, 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 }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2666, Value: 0x2d81), (Address: 0x2668, Value: 0x0000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf849, 0x0cd1, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2cec, Value: 0x255a), (Address: 0x2cee, Value: 0x0000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf847, 0x7c96, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, 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 }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x229a, Value: 0x23d7), (Address: 0x229c, Value: 0x0000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf846, 0xacaf, 0x4770, 0xe7fe }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2488, Value: 0x5f88), (Address: 0x248a, Value: 0x0025), (Address: 0x248c, Value: 0x2400) },
}, },
// STR (imm12) // STR (imm12)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8cc, 0x1a6e, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x2a6e, Value: 0x2000), (Address: 0x2a70, Value: 0x0000) },
}, },
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8c9, 0xcfc1, 0x4770, 0xe7fe }, 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 }, 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 }, 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) }, 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 }, 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 }, 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 }, 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) }, 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 }, 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 }, 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 }, 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) }, 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 }, 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 }, 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) }, MemoryDelta = new (ulong Address, ushort Value)[] { (Address: 0x228e, Value: 0x008e), (Address: 0x2290, Value: 0x0020), (Address: 0x2292, Value: 0x2200) },
}, },
// LDRB (imm8) // LDRB (imm8)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf816, 0x1c48, 0x4770, 0xe7fe }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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) // LDRB (imm12)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf892, 0xcc8f, 0x4770, 0xe7fe }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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) // LDRH (imm8)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf834, 0x89d8, 0x4770, 0xe7fe }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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) // LDRH (imm12)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8b7, 0x92fc, 0x4770, 0xe7fe }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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) // LDR (imm8)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf85b, 0x3fd1, 0x4770, 0xe7fe }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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) // LDR (imm12)
new PrecomputedMemoryThumbTestCase() new()
{ {
Instructions = new ushort[] { 0xf8d1, 0xc65e, 0x4770, 0xe7fe }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 }, 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 internal class EnvironmentTests
{ {
#pragma warning disable IDE0052 // Remove unread private member
private static Translator _translator; 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. // Create a translator, as one is needed to register the signal handler or emit methods.
_translator ??= new Translator(new JitMemoryAllocator(), new MockMemoryManager(), true); _translator ??= new Translator(new JitMemoryAllocator(), new MockMemoryManager(), true);
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private float GetDenormal() private static float GetDenormal()
{ {
return BitConverter.Int32BitsToSingle(1); return BitConverter.Int32BitsToSingle(1);
} }
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private float GetZero() private static float GetZero()
{ {
return BitConverter.Int32BitsToSingle(0); return BitConverter.Int32BitsToSingle(0);
} }
@ -53,7 +55,7 @@ namespace Ryujinx.Tests.Cpu
if (test < 4f) if (test < 4f)
{ {
throw new System.Exception("Sanity check."); throw new Exception("Sanity check.");
} }
isFz = GetDenormal() + GetZero() == 0f; isFz = GetDenormal() + GetZero() == 0f;
@ -62,7 +64,7 @@ namespace Ryujinx.Tests.Cpu
{ {
if (test >= 4f) if (test >= 4f)
{ {
throw new System.Exception("Always throws."); throw new Exception("Always throws.");
} }
} }
catch catch

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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