Add Mrs & Msr (Nzcv) Inst., with Tests.
This commit is contained in:
parent
f0188bb345
commit
7bace611ee
3 changed files with 113 additions and 0 deletions
|
@ -32,6 +32,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
case 0b11_011_0000_0000_001: dlg = new _U64(NativeInterface.GetCtrEl0); break;
|
||||
case 0b11_011_0000_0000_111: dlg = new _U64(NativeInterface.GetDczidEl0); break;
|
||||
case 0b11_011_0100_0010_000: dlg = new _U64(NativeInterface.GetNzcv); break;
|
||||
case 0b11_011_0100_0100_000: dlg = new _U64(NativeInterface.GetFpcr); break;
|
||||
case 0b11_011_0100_0100_001: dlg = new _U64(NativeInterface.GetFpsr); break;
|
||||
case 0b11_011_1101_0000_010: dlg = new _U64(NativeInterface.GetTpidrEl0); break;
|
||||
|
@ -53,6 +54,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
switch (GetPackedId(op))
|
||||
{
|
||||
case 0b11_011_0100_0010_000: dlg = new _Void_U64(NativeInterface.SetNzcv); break;
|
||||
case 0b11_011_0100_0100_000: dlg = new _Void_U64(NativeInterface.SetFpcr); break;
|
||||
case 0b11_011_0100_0100_001: dlg = new _Void_U64(NativeInterface.SetFpsr); break;
|
||||
case 0b11_011_1101_0000_010: dlg = new _Void_U64(NativeInterface.SetTpidrEl0); break;
|
||||
|
|
|
@ -77,6 +77,25 @@ namespace ARMeilleure.Instructions
|
|||
return (ulong)GetContext().DczidEl0;
|
||||
}
|
||||
|
||||
public static ulong GetNzcv()
|
||||
{
|
||||
void Insert(ref ulong value, PState bit, bool flag)
|
||||
{
|
||||
value |= (flag ? 1UL : 0UL) << (int)bit;
|
||||
}
|
||||
|
||||
ExecutionContext context = GetContext();
|
||||
|
||||
ulong value = 0UL;
|
||||
|
||||
Insert(ref value, PState.VFlag, context.GetPstateFlag(PState.VFlag));
|
||||
Insert(ref value, PState.CFlag, context.GetPstateFlag(PState.CFlag));
|
||||
Insert(ref value, PState.ZFlag, context.GetPstateFlag(PState.ZFlag));
|
||||
Insert(ref value, PState.NFlag, context.GetPstateFlag(PState.NFlag));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ulong GetFpcr()
|
||||
{
|
||||
return (ulong)GetContext().Fpcr;
|
||||
|
@ -107,6 +126,25 @@ namespace ARMeilleure.Instructions
|
|||
return GetContext().CntpctEl0;
|
||||
}
|
||||
|
||||
public static void SetNzcv(ulong value)
|
||||
{
|
||||
bool Extract(ulong value, PState bit)
|
||||
{
|
||||
value >>= (int)bit;
|
||||
|
||||
value &= 1UL;
|
||||
|
||||
return value != 0UL;
|
||||
}
|
||||
|
||||
ExecutionContext context = GetContext();
|
||||
|
||||
context.SetPstateFlag(PState.VFlag, Extract(value, PState.VFlag));
|
||||
context.SetPstateFlag(PState.CFlag, Extract(value, PState.CFlag));
|
||||
context.SetPstateFlag(PState.ZFlag, Extract(value, PState.ZFlag));
|
||||
context.SetPstateFlag(PState.NFlag, Extract(value, PState.NFlag));
|
||||
}
|
||||
|
||||
public static void SetFpcr(ulong value)
|
||||
{
|
||||
GetContext().Fpcr = (FPCR)value;
|
||||
|
|
73
Ryujinx.Tests/Cpu/CpuTestSystem.cs
Normal file
73
Ryujinx.Tests/Cpu/CpuTestSystem.cs
Normal file
|
@ -0,0 +1,73 @@
|
|||
#define System
|
||||
|
||||
using ARMeilleure.State;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Tests.Cpu
|
||||
{
|
||||
[Category("System")]
|
||||
public sealed class CpuTestSystem : CpuTest
|
||||
{
|
||||
#if System
|
||||
|
||||
#region "ValueSource (Types)"
|
||||
private static IEnumerable<ulong> _GenNzcv_()
|
||||
{
|
||||
yield return 0x0000000000000000ul;
|
||||
yield return 0x7FFFFFFFFFFFFFFFul;
|
||||
yield return 0x8000000000000000ul;
|
||||
yield return 0xFFFFFFFFFFFFFFFFul;
|
||||
|
||||
bool v = TestContext.CurrentContext.Random.NextBool();
|
||||
bool c = TestContext.CurrentContext.Random.NextBool();
|
||||
bool z = TestContext.CurrentContext.Random.NextBool();
|
||||
bool n = TestContext.CurrentContext.Random.NextBool();
|
||||
|
||||
ulong rnd = 0UL;
|
||||
|
||||
rnd |= (v ? 1UL : 0UL) << (int)PState.VFlag;
|
||||
rnd |= (c ? 1UL : 0UL) << (int)PState.CFlag;
|
||||
rnd |= (z ? 1UL : 0UL) << (int)PState.ZFlag;
|
||||
rnd |= (n ? 1UL : 0UL) << (int)PState.NFlag;
|
||||
|
||||
yield return rnd;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "ValueSource (Opcodes)"
|
||||
private static uint[] _MrsMsr_Nzcv_()
|
||||
{
|
||||
return new uint[]
|
||||
{
|
||||
0xD53B4200u, // MRS X0, NZCV
|
||||
0xD51B4200u // MSR NZCV, X0
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
private const int RndCnt = 2;
|
||||
|
||||
[Test, Pairwise]
|
||||
public void MrsMsr_Nzcv([ValueSource("_MrsMsr_Nzcv_")] uint opcodes,
|
||||
[Values(0u, 1u, 31u)] uint rt,
|
||||
[ValueSource("_GenNzcv_")] [Random(RndCnt)] ulong xt)
|
||||
{
|
||||
opcodes |= (rt & 31) << 0;
|
||||
|
||||
bool v = TestContext.CurrentContext.Random.NextBool();
|
||||
bool c = TestContext.CurrentContext.Random.NextBool();
|
||||
bool z = TestContext.CurrentContext.Random.NextBool();
|
||||
bool n = TestContext.CurrentContext.Random.NextBool();
|
||||
|
||||
ulong x31 = TestContext.CurrentContext.Random.NextULong();
|
||||
|
||||
SingleOpcode(opcodes, x0: xt, x1: xt, x31: x31, overflow: v, carry: c, zero: z, negative: n);
|
||||
|
||||
CompareAgainstUnicorn();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue