Tests: Prepare for thumb tests

This commit is contained in:
merry 2022-02-10 17:15:31 +00:00
parent e1bbf8d7b9
commit d4fe1ee5a8
3 changed files with 63 additions and 3 deletions

View file

@ -41,8 +41,8 @@ namespace Ryujinx.Tests.Unicorn
public uint PC public uint PC
{ {
get => GetRegister(Arm32Register.PC); get => GetRegister(Arm32Register.PC) & 0xfffffffeu;
set => SetRegister(Arm32Register.PC, value); set => SetRegister(Arm32Register.PC, (value & 0xfffffffeu) | (ThumbFlag ? 1u : 0u));
} }
public uint CPSR public uint CPSR
@ -87,6 +87,16 @@ namespace Ryujinx.Tests.Unicorn
set => CPSR = (CPSR & ~0x80000000u) | (value ? 0x80000000u : 0u); set => CPSR = (CPSR & ~0x80000000u) | (value ? 0x80000000u : 0u);
} }
public bool ThumbFlag
{
get => (CPSR & 0x00000020u) != 0;
set
{
CPSR = (CPSR & ~0x00000020u) | (value ? 0x00000020u : 0u);
SetRegister(Arm32Register.PC, (GetRegister(Arm32Register.PC) & 0xfffffffeu) | (value ? 1u : 0u));
}
}
public UnicornAArch32() public UnicornAArch32()
{ {
Interface.Checked(Interface.uc_open(UnicornArch.UC_ARCH_ARM, UnicornMode.UC_MODE_LITTLE_ENDIAN, out uc)); Interface.Checked(Interface.uc_open(UnicornArch.UC_ARCH_ARM, UnicornMode.UC_MODE_LITTLE_ENDIAN, out uc));

View file

@ -106,6 +106,18 @@ namespace Ryujinx.Tests.Cpu
_currAddress += 4; _currAddress += 4;
} }
protected void ThumbOpcode(ushort opcode)
{
_memory.Write(_currAddress, opcode);
if (_unicornAvailable)
{
_unicornEmu.MemoryWrite16(_currAddress, opcode);
}
_currAddress += 2;
}
protected ExecutionContext GetContext() => _context; protected ExecutionContext GetContext() => _context;
protected void SetContext(uint r0 = 0, protected void SetContext(uint r0 = 0,
@ -126,7 +138,8 @@ namespace Ryujinx.Tests.Cpu
bool carry = false, bool carry = false,
bool zero = false, bool zero = false,
bool negative = false, bool negative = false,
int fpscr = 0) int fpscr = 0,
bool thumb = false)
{ {
_context.SetX(0, r0); _context.SetX(0, r0);
_context.SetX(1, r1); _context.SetX(1, r1);
@ -151,6 +164,8 @@ namespace Ryujinx.Tests.Cpu
SetFpscr((uint)fpscr); SetFpscr((uint)fpscr);
_context.SetPstateFlag(PState.TFlag, thumb);
if (_unicornAvailable) if (_unicornAvailable)
{ {
_unicornEmu.R[0] = r0; _unicornEmu.R[0] = r0;
@ -175,6 +190,8 @@ namespace Ryujinx.Tests.Cpu
_unicornEmu.NegativeFlag = negative; _unicornEmu.NegativeFlag = negative;
_unicornEmu.Fpscr = fpscr; _unicornEmu.Fpscr = fpscr;
_unicornEmu.ThumbFlag = thumb;
} }
} }
@ -218,6 +235,28 @@ namespace Ryujinx.Tests.Cpu
return GetContext(); return GetContext();
} }
protected ExecutionContext SingleThumbOpcode(ushort opcode,
uint r0 = 0,
uint r1 = 0,
uint r2 = 0,
uint r3 = 0,
uint sp = 0,
bool saturation = false,
bool overflow = false,
bool carry = false,
bool zero = false,
bool negative = false,
int fpscr = 0,
bool runUnicorn = true)
{
ThumbOpcode(opcode);
ThumbOpcode(0x4770); // BX LR
SetContext(r0, r1, r2, r3, sp, default, default, default, default, default, default, default, default, saturation, overflow, carry, zero, negative, fpscr, thumb: true);
ExecuteOpcodes(runUnicorn);
return GetContext();
}
protected void SetWorkingMemory(uint offset, byte[] data) protected void SetWorkingMemory(uint offset, byte[] data)
{ {
_memory.Write(DataBaseAddress + offset, data); _memory.Write(DataBaseAddress + offset, data);

View file

@ -0,0 +1,11 @@
using NUnit.Framework;
using System;
namespace Ryujinx.Tests.Cpu
{
[Category("Thumb")]
public sealed class CpuTestThumb : CpuTest32
{
private const int RndCnt = 2;
}
}