Compare commits

..

7 Commits

Author SHA1 Message Date
Ac_K
aac7bbd378 olsc: Implement GetSaveDataBackupSetting (#3190)
* olsc: Implement GetSaveDataBackupSetting

This PR implement GetSaveDataBackupSetting of OLSC service which is now needed by ACNH 2.0.5. The game is playable as usual if you use the same user profile as the original save file (I don't know if it was the case before), everything is checked by RE.

* addresses gdkchan feedback
2022-03-12 18:38:49 +01:00
darko1979
bed516bfda Implement rotate stick 90 degrees clockwise (#3084)
* Implement swapping sticks

* Rotate 90 degrees clockwise

Co-authored-by: matesic.darko@gmail.com <Darkman1979>
2022-03-12 18:23:48 +01:00
gdkchan
69b05f9918 Fix GetUserDisableCount NRE (#3187) 2022-03-12 18:12:12 +01:00
gdkchan
fb7c80e928 Limit number of events that can be retrieved from GetDisplayVSyncEvent (#3188)
* Limit number of events that can be retrieved from GetDisplayVSyncEvent

* Cleaning

* Rename openDisplayInfos -> openDisplays
2022-03-12 17:56:19 +01:00
merry
bb2f9df0a1 KThread: Fix GetPsr mask (#3180)
* ExecutionContext: GetPstate / SetPstate

* Put it in NativeContext

* KThread: Fix GetPsr mask

* ExecutionContext: Turn methods into Pstate property

* Address nit
2022-03-11 03:16:32 +01:00
Mary
54bfaa125d amadeus: Fix wrong Span usage in CopyHistories (#3181)
Fix a copypasta from the original Amadeus PR causing invalid
CopyHistories output.

Also added a missing size check.

This fix a crash in Mononoke Slashdown
2022-03-07 09:49:29 +01:00
merry
7af9fcbc06 T32: Implement Data Processing (Modified Immediate) instructions (#3178)
* T32: Implement Data Processing (Modified Immediate) instructions

* Update tests

* switch -> lookup table
2022-03-06 22:25:01 +01:00
20 changed files with 720 additions and 38 deletions

View File

@@ -0,0 +1,38 @@
using ARMeilleure.Common;
using System.Runtime.Intrinsics;
namespace ARMeilleure.Decoders
{
class OpCodeT32AluImm : OpCodeT32Alu, IOpCode32AluImm
{
public int Immediate { get; }
public bool IsRotated { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluImm(inst, address, opCode);
private static readonly Vector128<int> _factor = Vector128.Create(1, 0x00010001, 0x01000100, 0x01010101);
public OpCodeT32AluImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
int imm8 = (opCode >> 0) & 0xff;
int imm3 = (opCode >> 12) & 7;
int imm1 = (opCode >> 26) & 1;
int imm12 = imm8 | (imm3 << 8) | (imm1 << 11);
if ((imm12 >> 10) == 0)
{
Immediate = imm8 * _factor.GetElement((imm12 >> 8) & 3);
IsRotated = false;
}
else
{
int shift = imm12 >> 7;
Immediate = BitUtils.RotateRight(0x80 | (imm12 & 0x7f), shift, 32);
IsRotated = shift != 0;
}
}
}
}

View File

@@ -1048,25 +1048,41 @@ namespace ARMeilleure.Decoders
#region "OpCode Table (AArch32, T32)" #region "OpCode Table (AArch32, T32)"
// Base // Base
SetT32("11101011010xxxxx0xxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, OpCodeT32AluRsImm.Create); SetT32("11101011010xxxxx0xxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, OpCodeT32AluRsImm.Create);
SetT32("11110x01010xxxxx0xxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, OpCodeT32AluImm.Create);
SetT32("11101011000<xxxx0xxx<<<<xxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT32AluRsImm.Create); SetT32("11101011000<xxxx0xxx<<<<xxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT32AluRsImm.Create);
SetT32("11110x01000<xxxx0xxx<<<<xxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT32AluImm.Create);
SetT32("11101010000<xxxx0xxx<<<<xxxxxxxx", InstName.And, InstEmit32.And, OpCodeT32AluRsImm.Create); SetT32("11101010000<xxxx0xxx<<<<xxxxxxxx", InstName.And, InstEmit32.And, OpCodeT32AluRsImm.Create);
SetT32("11110x00000<xxxx0xxx<<<<xxxxxxxx", InstName.And, InstEmit32.And, OpCodeT32AluImm.Create);
SetT32("11110x<<<xxxxxxx10x0xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm20.Create); SetT32("11110x<<<xxxxxxx10x0xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm20.Create);
SetT32("11110xxxxxxxxxxx10x1xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm24.Create); SetT32("11110xxxxxxxxxxx10x1xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm24.Create);
SetT32("11101010001xxxxx0xxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT32AluRsImm.Create); SetT32("11101010001xxxxx0xxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT32AluRsImm.Create);
SetT32("11110x00001xxxxx0xxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT32AluImm.Create);
SetT32("11110xxxxxxxxxxx11x1xxxxxxxxxxxx", InstName.Bl, InstEmit32.Bl, OpCodeT32BImm24.Create); SetT32("11110xxxxxxxxxxx11x1xxxxxxxxxxxx", InstName.Bl, InstEmit32.Bl, OpCodeT32BImm24.Create);
SetT32("11110xxxxxxxxxxx11x0xxxxxxxxxxx0", InstName.Blx, InstEmit32.Blx, OpCodeT32BImm24.Create); SetT32("11110xxxxxxxxxxx11x0xxxxxxxxxxx0", InstName.Blx, InstEmit32.Blx, OpCodeT32BImm24.Create);
SetT32("111010110001xxxx0xxx1111xxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT32AluRsImm.Create); SetT32("111010110001xxxx0xxx1111xxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT32AluRsImm.Create);
SetT32("11110x010001xxxx0xxx1111xxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT32AluImm.Create);
SetT32("111010111011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluRsImm.Create); SetT32("111010111011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluRsImm.Create);
SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.Create);
SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create); SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create);
SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create);
SetT32("11101010010x11110xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32AluRsImm.Create); SetT32("11101010010x11110xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32AluRsImm.Create);
SetT32("11110x00010x11110xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32AluImm.Create);
SetT32("11101010011x11110xxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT32AluRsImm.Create); SetT32("11101010011x11110xxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT32AluRsImm.Create);
SetT32("11110x00011x11110xxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT32AluImm.Create);
SetT32("11101010011x<<<<0xxxxxxxxxxxxxxx", InstName.Orn, InstEmit32.Orn, OpCodeT32AluRsImm.Create); SetT32("11101010011x<<<<0xxxxxxxxxxxxxxx", InstName.Orn, InstEmit32.Orn, OpCodeT32AluRsImm.Create);
SetT32("11110x00011x<<<<0xxxxxxxxxxxxxxx", InstName.Orn, InstEmit32.Orn, OpCodeT32AluImm.Create);
SetT32("11101010010x<<<<0xxxxxxxxxxxxxxx", InstName.Orr, InstEmit32.Orr, OpCodeT32AluRsImm.Create); SetT32("11101010010x<<<<0xxxxxxxxxxxxxxx", InstName.Orr, InstEmit32.Orr, OpCodeT32AluRsImm.Create);
SetT32("11110x00010x<<<<0xxxxxxxxxxxxxxx", InstName.Orr, InstEmit32.Orr, OpCodeT32AluImm.Create);
SetT32("11101011110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluRsImm.Create); SetT32("11101011110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluRsImm.Create);
SetT32("11110x01110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluImm.Create);
SetT32("11101011011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluRsImm.Create); SetT32("11101011011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluRsImm.Create);
SetT32("11110x01011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluImm.Create);
SetT32("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create); SetT32("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create);
SetT32("11110x01101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluImm.Create);
SetT32("111010101001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluRsImm.Create); SetT32("111010101001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluRsImm.Create);
SetT32("11110x001001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluImm.Create);
SetT32("111010100001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluRsImm.Create); SetT32("111010100001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluRsImm.Create);
SetT32("11110x000001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluImm.Create);
#endregion #endregion
FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA); FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA);

View File

@@ -43,6 +43,12 @@ namespace ARMeilleure.State
public long TpidrEl0 { get; set; } public long TpidrEl0 { get; set; }
public long Tpidr { get; set; } public long Tpidr { get; set; }
public uint Pstate
{
get => _nativeContext.GetPstate();
set => _nativeContext.SetPstate(value);
}
public FPCR Fpcr { get; set; } public FPCR Fpcr { get; set; }
public FPSR Fpsr { get; set; } public FPSR Fpsr { get; set; }
public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz; public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz;

View File

@@ -95,6 +95,25 @@ namespace ARMeilleure.State
GetStorage().Flags[(int)flag] = value ? 1u : 0u; GetStorage().Flags[(int)flag] = value ? 1u : 0u;
} }
public unsafe uint GetPstate()
{
uint value = 0;
for (int flag = 0; flag < RegisterConsts.FlagsCount; flag++)
{
value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u;
}
return value;
}
public unsafe void SetPstate(uint value)
{
for (int flag = 0; flag < RegisterConsts.FlagsCount; flag++)
{
uint bit = 1u << flag;
GetStorage().Flags[flag] = (value & bit) == bit ? 1u : 0u;
}
}
public unsafe bool GetFPStateFlag(FPState flag) public unsafe bool GetFPStateFlag(FPState flag)
{ {
if ((uint)flag >= RegisterConsts.FpFlagsCount) if ((uint)flag >= RegisterConsts.FpFlagsCount)

View File

@@ -149,11 +149,21 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
Span<byte> targetSpan = performanceOutput.Slice(nextOffset); Span<byte> targetSpan = performanceOutput.Slice(nextOffset);
// NOTE: We check for the space for two headers for the final blank header.
int requiredSpace = Unsafe.SizeOf<THeader>() + Unsafe.SizeOf<TEntry>() * inputHeader.GetEntryCount()
+ Unsafe.SizeOf<TEntryDetail>() * inputHeader.GetEntryDetailCount()
+ Unsafe.SizeOf<THeader>();
if (targetSpan.Length < requiredSpace)
{
break;
}
ref THeader outputHeader = ref MemoryMarshal.Cast<byte, THeader>(targetSpan)[0]; ref THeader outputHeader = ref MemoryMarshal.Cast<byte, THeader>(targetSpan)[0];
nextOffset += Unsafe.SizeOf<THeader>(); nextOffset += Unsafe.SizeOf<THeader>();
Span<TEntry> outputEntries = MemoryMarshal.Cast<byte, TEntry>(targetSpan.Slice(nextOffset)); Span<TEntry> outputEntries = MemoryMarshal.Cast<byte, TEntry>(performanceOutput.Slice(nextOffset));
int totalProcessingTime = 0; int totalProcessingTime = 0;
@@ -175,7 +185,7 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
} }
} }
Span<TEntryDetail> outputEntriesDetail = MemoryMarshal.Cast<byte, TEntryDetail>(targetSpan.Slice(nextOffset)); Span<TEntryDetail> outputEntriesDetail = MemoryMarshal.Cast<byte, TEntryDetail>(performanceOutput.Slice(nextOffset));
int effectiveEntryDetailCount = 0; int effectiveEntryDetailCount = 0;

View File

@@ -5,6 +5,7 @@
public Stick Joystick { get; set; } public Stick Joystick { get; set; }
public bool InvertStickX { get; set; } public bool InvertStickX { get; set; }
public bool InvertStickY { get; set; } public bool InvertStickY { get; set; }
public bool Rotate90CW { get; set; }
public Button StickButton { get; set; } public Button StickButton { get; set; }
} }
} }

View File

@@ -751,7 +751,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{ {
KThread currentThread = KernelStatic.GetCurrentThread(); KThread currentThread = KernelStatic.GetCurrentThread();
if (currentThread.Owner != null && if (currentThread.Context.Running &&
currentThread.Owner != null &&
currentThread.GetUserDisableCount() != 0 && currentThread.GetUserDisableCount() != 0 &&
currentThread.Owner.PinnedThreads[currentThread.CurrentCore] == null) currentThread.Owner.PinnedThreads[currentThread.CurrentCore] == null)
{ {

View File

@@ -658,10 +658,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
private static uint GetPsr(ARMeilleure.State.ExecutionContext context) private static uint GetPsr(ARMeilleure.State.ExecutionContext context)
{ {
return (context.GetPstateFlag(ARMeilleure.State.PState.NFlag) ? (1U << (int)ARMeilleure.State.PState.NFlag) : 0U) | return context.Pstate & 0xFF0FFE20;
(context.GetPstateFlag(ARMeilleure.State.PState.ZFlag) ? (1U << (int)ARMeilleure.State.PState.ZFlag) : 0U) |
(context.GetPstateFlag(ARMeilleure.State.PState.CFlag) ? (1U << (int)ARMeilleure.State.PState.CFlag) : 0U) |
(context.GetPstateFlag(ARMeilleure.State.PState.VFlag) ? (1U << (int)ARMeilleure.State.PState.VFlag) : 0U);
} }
private ThreadContext GetCurrentContext() private ThreadContext GetCurrentContext()
@@ -1371,7 +1368,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
PreferredCore = _originalPreferredCore; PreferredCore = _originalPreferredCore;
AffinityMask = _originalAffinityMask; AffinityMask = _originalAffinityMask;
if (AffinityMask != affinityMask) if (AffinityMask != affinityMask)
{ {
if ((AffinityMask & 1UL << ActiveCore) != 0) if ((AffinityMask & 1UL << ActiveCore) != 0)

View File

@@ -1,13 +1,15 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Account.Acc;
using System.Collections.Generic;
namespace Ryujinx.HLE.HOS.Services.Olsc namespace Ryujinx.HLE.HOS.Services.Olsc
{ {
[Service("olsc:u")] // 10.0.0+ [Service("olsc:u")] // 10.0.0+
class IOlscServiceForApplication : IpcService class IOlscServiceForApplication : IpcService
{ {
private bool _initialized; private bool _initialized;
private Dictionary<UserId, bool> _saveDataBackupSettingDatabase;
public IOlscServiceForApplication(ServiceCtx context) { } public IOlscServiceForApplication(ServiceCtx context) { }
@@ -16,7 +18,9 @@ namespace Ryujinx.HLE.HOS.Services.Olsc
public ResultCode Initialize(ServiceCtx context) public ResultCode Initialize(ServiceCtx context)
{ {
// NOTE: Service call arp:r GetApplicationInstanceUnregistrationNotifier with the pid and initialize some internal struct. // NOTE: Service call arp:r GetApplicationInstanceUnregistrationNotifier with the pid and initialize some internal struct.
// Since we will not support online savedata backup. It's fine to stub it for now. // Since we will not support online savedata backup, it's fine to stub it for now.
_saveDataBackupSettingDatabase = new Dictionary<UserId, bool>();
_initialized = true; _initialized = true;
@@ -25,12 +29,11 @@ namespace Ryujinx.HLE.HOS.Services.Olsc
return ResultCode.Success; return ResultCode.Success;
} }
[CommandHipc(14)] [CommandHipc(13)]
// SetSaveDataBackupSettingEnabled(nn::account::Uid, bool) // GetSaveDataBackupSetting(nn::account::Uid) -> u8
public ResultCode SetSaveDataBackupSettingEnabled(ServiceCtx context) public ResultCode GetSaveDataBackupSetting(ServiceCtx context)
{ {
UserId userId = context.RequestData.ReadStruct<UserId>(); UserId userId = context.RequestData.ReadStruct<UserId>();
ulong saveDataBackupSettingEnabled = context.RequestData.ReadUInt64();
if (!_initialized) if (!_initialized)
{ {
@@ -42,8 +45,42 @@ namespace Ryujinx.HLE.HOS.Services.Olsc
return ResultCode.NullArgument; return ResultCode.NullArgument;
} }
// NOTE: Service store the UserId and the boolean in an internal SaveDataBackupSettingDatabase object. if (_saveDataBackupSettingDatabase[userId])
// Since we will not support online savedata backup. It's fine to stub it for now. {
context.ResponseData.Write((byte)1); // TODO: Determine value.
}
else
{
context.ResponseData.Write((byte)2); // TODO: Determine value.
}
// NOTE: Since we will not support online savedata backup, it's fine to stub it for now.
Logger.Stub?.PrintStub(LogClass.ServiceOlsc, new { userId });
return ResultCode.Success;
}
[CommandHipc(14)]
// SetSaveDataBackupSettingEnabled(nn::account::Uid, bool)
public ResultCode SetSaveDataBackupSettingEnabled(ServiceCtx context)
{
bool saveDataBackupSettingEnabled = context.RequestData.ReadUInt64() != 0;
UserId userId = context.RequestData.ReadStruct<UserId>();
if (!_initialized)
{
return ResultCode.NotInitialized;
}
if (userId.IsNull)
{
return ResultCode.NullArgument;
}
_saveDataBackupSettingDatabase[userId] = saveDataBackupSettingEnabled;
// NOTE: Since we will not support online savedata backup, it's fine to stub it for now.
Logger.Stub?.PrintStub(LogClass.ServiceOlsc, new { userId, saveDataBackupSettingEnabled }); Logger.Stub?.PrintStub(LogClass.ServiceOlsc, new { userId, saveDataBackupSettingEnabled });

View File

@@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
if (serviceType != ViServiceType.Application) if (serviceType != ViServiceType.Application)
{ {
return ResultCode.InvalidRange; return ResultCode.PermissionDenied;
} }
MakeObject(context, new IApplicationDisplayService(serviceType)); MakeObject(context, new IApplicationDisplayService(serviceType));

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
if (serviceType != ViServiceType.Manager) if (serviceType != ViServiceType.Manager)
{ {
return ResultCode.InvalidRange; return ResultCode.PermissionDenied;
} }
MakeObject(context, new IApplicationDisplayService(serviceType)); MakeObject(context, new IApplicationDisplayService(serviceType));

View File

@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
if (serviceType != ViServiceType.System) if (serviceType != ViServiceType.System)
{ {
return ResultCode.InvalidRange; return ResultCode.PermissionDenied;
} }
MakeObject(context, new IApplicationDisplayService(serviceType)); MakeObject(context, new IApplicationDisplayService(serviceType));

View File

@@ -9,7 +9,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
InvalidArguments = (1 << ErrorCodeShift) | ModuleId, InvalidArguments = (1 << ErrorCodeShift) | ModuleId,
InvalidLayerSize = (4 << ErrorCodeShift) | ModuleId, InvalidLayerSize = (4 << ErrorCodeShift) | ModuleId,
InvalidRange = (5 << ErrorCodeShift) | ModuleId, PermissionDenied = (5 << ErrorCodeShift) | ModuleId,
InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId, InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId,
InvalidValue = (7 << ErrorCodeShift) | ModuleId, InvalidValue = (7 << ErrorCodeShift) | ModuleId,
AlreadyOpened = (9 << ErrorCodeShift) | ModuleId AlreadyOpened = (9 << ErrorCodeShift) | ModuleId

View File

@@ -1,7 +1,6 @@
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory; using Ryujinx.Common.Memory;
using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Applets; using Ryujinx.HLE.HOS.Applets;
using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Common;
@@ -22,16 +21,21 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{ {
private readonly ViServiceType _serviceType; private readonly ViServiceType _serviceType;
private readonly List<DisplayInfo> _displayInfo; private class DisplayState
private readonly Dictionary<ulong, DisplayInfo> _openDisplayInfo; {
public int RetrievedEventsCount;
}
private readonly List<DisplayInfo> _displayInfo;
private readonly Dictionary<ulong, DisplayState> _openDisplays;
private int _vsyncEventHandle; private int _vsyncEventHandle;
public IApplicationDisplayService(ViServiceType serviceType) public IApplicationDisplayService(ViServiceType serviceType)
{ {
_serviceType = serviceType; _serviceType = serviceType;
_displayInfo = new List<DisplayInfo>(); _displayInfo = new List<DisplayInfo>();
_openDisplayInfo = new Dictionary<ulong, DisplayInfo>(); _openDisplays = new Dictionary<ulong, DisplayState>();
void AddDisplayInfo(string name, bool layerLimitEnabled, ulong layerLimitMax, ulong width, ulong height) void AddDisplayInfo(string name, bool layerLimitEnabled, ulong layerLimitMax, ulong width, ulong height)
{ {
@@ -64,7 +68,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
// FIXME: Should be _serviceType != ViServiceType.Application but guests crashes if we do this check. // FIXME: Should be _serviceType != ViServiceType.Application but guests crashes if we do this check.
if (_serviceType > ViServiceType.System) if (_serviceType > ViServiceType.System)
{ {
return ResultCode.InvalidRange; return ResultCode.PermissionDenied;
} }
MakeObject(context, new HOSBinderDriverServer()); MakeObject(context, new HOSBinderDriverServer());
@@ -79,7 +83,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
// FIXME: Should be _serviceType == ViServiceType.System but guests crashes if we do this check. // FIXME: Should be _serviceType == ViServiceType.System but guests crashes if we do this check.
if (_serviceType > ViServiceType.System) if (_serviceType > ViServiceType.System)
{ {
return ResultCode.InvalidRange; return ResultCode.PermissionDenied;
} }
MakeObject(context, new ISystemDisplayService(this)); MakeObject(context, new ISystemDisplayService(this));
@@ -93,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{ {
if (_serviceType > ViServiceType.System) if (_serviceType > ViServiceType.System)
{ {
return ResultCode.InvalidRange; return ResultCode.PermissionDenied;
} }
MakeObject(context, new IManagerDisplayService(this)); MakeObject(context, new IManagerDisplayService(this));
@@ -107,7 +111,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{ {
if (_serviceType > ViServiceType.System) if (_serviceType > ViServiceType.System)
{ {
return ResultCode.InvalidRange; return ResultCode.PermissionDenied;
} }
MakeObject(context, new HOSBinderDriverServer()); MakeObject(context, new HOSBinderDriverServer());
@@ -174,7 +178,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
return ResultCode.InvalidValue; return ResultCode.InvalidValue;
} }
if (!_openDisplayInfo.TryAdd((ulong)displayId, _displayInfo[displayId])) if (!_openDisplays.TryAdd((ulong)displayId, new DisplayState()))
{ {
return ResultCode.AlreadyOpened; return ResultCode.AlreadyOpened;
} }
@@ -190,7 +194,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{ {
ulong displayId = context.RequestData.ReadUInt64(); ulong displayId = context.RequestData.ReadUInt64();
if (!_openDisplayInfo.Remove(displayId)) if (!_openDisplays.Remove(displayId))
{ {
return ResultCode.InvalidValue; return ResultCode.InvalidValue;
} }
@@ -454,11 +458,16 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
{ {
ulong displayId = context.RequestData.ReadUInt64(); ulong displayId = context.RequestData.ReadUInt64();
if (!_openDisplayInfo.ContainsKey(displayId)) if (!_openDisplays.TryGetValue(displayId, out DisplayState displayState))
{ {
return ResultCode.InvalidValue; return ResultCode.InvalidValue;
} }
if (displayState.RetrievedEventsCount > 0)
{
return ResultCode.PermissionDenied;
}
if (_vsyncEventHandle == 0) if (_vsyncEventHandle == 0)
{ {
if (context.Process.HandleTable.GenerateHandle(context.Device.System.VsyncEvent.ReadableEvent, out _vsyncEventHandle) != KernelResult.Success) if (context.Process.HandleTable.GenerateHandle(context.Device.System.VsyncEvent.ReadableEvent, out _vsyncEventHandle) != KernelResult.Success)
@@ -467,6 +476,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
} }
} }
displayState.RetrievedEventsCount++;
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_vsyncEventHandle); context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_vsyncEventHandle);
return ResultCode.Success; return ResultCode.Success;

View File

@@ -220,6 +220,7 @@ namespace Ryujinx.Headless.SDL2
StickButton = ConfigGamepadInputId.LeftStick, StickButton = ConfigGamepadInputId.LeftStick,
InvertStickX = false, InvertStickX = false,
InvertStickY = false, InvertStickY = false,
Rotate90CW = false,
}, },
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId> RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
@@ -241,6 +242,7 @@ namespace Ryujinx.Headless.SDL2
StickButton = ConfigGamepadInputId.RightStick, StickButton = ConfigGamepadInputId.RightStick,
InvertStickX = false, InvertStickX = false,
InvertStickY = false, InvertStickY = false,
Rotate90CW = false,
}, },
Motion = new StandardMotionConfigController Motion = new StandardMotionConfigController

View File

@@ -350,6 +350,14 @@ namespace Ryujinx.Input.SDL2
{ {
resultY = -resultY; resultY = -resultY;
} }
if ((inputId == StickInputId.Left && _configuration.LeftJoyconStick.Rotate90CW) ||
(inputId == StickInputId.Right && _configuration.RightJoyconStick.Rotate90CW))
{
float temp = resultX;
resultX = resultY;
resultY = -temp;
}
} }
return (resultX, resultY); return (resultX, resultY);

View File

@@ -283,10 +283,7 @@ namespace Ryujinx.Tests.Cpu
} }
uint finalCpsr = test.FinalRegs[15]; uint finalCpsr = test.FinalRegs[15];
for (int i = 0; i < 32; i++) Assert.That(GetContext().Pstate, Is.EqualTo(finalCpsr));
{
Assert.That(GetContext().GetPstateFlag((PState)i), Is.EqualTo((finalCpsr & (1u << i)) != 0));
}
} }
protected void SetWorkingMemory(uint offset, byte[] data) protected void SetWorkingMemory(uint offset, byte[] data)

View File

@@ -13,6 +13,12 @@ namespace Ryujinx.Tests.Cpu
RunPrecomputedTestCase(test); RunPrecomputedTestCase(test);
} }
[Test]
public void TestT32AluImm([ValueSource(nameof(ImmTestCases))] PrecomputedThumbTestCase test)
{
RunPrecomputedTestCase(test);
}
public static readonly PrecomputedThumbTestCase[] RsImmTestCases = public static readonly PrecomputedThumbTestCase[] RsImmTestCases =
{ {
// TST (reg) // TST (reg)
@@ -506,5 +512,505 @@ namespace Ryujinx.Tests.Cpu
FinalRegs = new uint[] { 0x79108ff6, 0x0cb1e662, 0x9eb9ffed, 0x1ee4d3de, 0x7a8fa20a, 0x1db7e216, 0x6fc42752, 0x9cb6cdad, 0xa497a582, 0x654c446f, 0xcbb31efc, 0x601e6995, 0xe328af35, 0x824026e7, 0x00000000, 0x100001d0 }, FinalRegs = new uint[] { 0x79108ff6, 0x0cb1e662, 0x9eb9ffed, 0x1ee4d3de, 0x7a8fa20a, 0x1db7e216, 0x6fc42752, 0x9cb6cdad, 0xa497a582, 0x654c446f, 0xcbb31efc, 0x601e6995, 0xe328af35, 0x824026e7, 0x00000000, 0x100001d0 },
}, },
}; };
public static readonly PrecomputedThumbTestCase[] ImmTestCases =
{
// TST (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf018, 0x0fd4, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xf5a1b919, 0x37ee0ad4, 0xec1bbb30, 0x8345ecb1, 0xf733e93e, 0x76668927, 0xa9b16176, 0x34b9678e, 0xa6167f8b, 0xea4f20a9, 0x45345e75, 0xc8a2ea55, 0xae108472, 0x67b5e3a4, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0xf5a1b919, 0x37ee0ad4, 0xec1bbb30, 0x8345ecb1, 0xf733e93e, 0x76668927, 0xa9b16176, 0x34b9678e, 0xa6167f8b, 0xea4f20a9, 0x45345e75, 0xc8a2ea55, 0xae108472, 0x67b5e3a4, 0x00000001, 0x300001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf41b, 0x1fff, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xfc928b9b, 0xeff1f0a6, 0xe1cd22ba, 0xef1e4a75, 0x10779ef3, 0x3b003004, 0x7a532842, 0x2e71a8c4, 0x62b71ce6, 0x5ffcf3ce, 0xdbe8efa1, 0x86822f2b, 0x560da6b6, 0x46550850, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0xfc928b9b, 0xeff1f0a6, 0xe1cd22ba, 0xef1e4a75, 0x10779ef3, 0x3b003004, 0x7a532842, 0x2e71a8c4, 0x62b71ce6, 0x5ffcf3ce, 0xdbe8efa1, 0x86822f2b, 0x560da6b6, 0x46550850, 0x00000001, 0x100001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf416, 0x7f97, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd0ba5d0a, 0xc8fa5c53, 0xac3069cb, 0x4be76d89, 0xcc9b4f47, 0x36984914, 0xd49fe0a5, 0x7d80c756, 0x8210fb6d, 0xcb498541, 0xc366597f, 0xacef4405, 0xdf6341a9, 0x6a1124b8, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0xd0ba5d0a, 0xc8fa5c53, 0xac3069cb, 0x4be76d89, 0xcc9b4f47, 0x36984914, 0xd49fe0a5, 0x7d80c756, 0x8210fb6d, 0xcb498541, 0xc366597f, 0xacef4405, 0xdf6341a9, 0x6a1124b8, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf016, 0x0f12, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xb8568ac2, 0x67a7ee09, 0x266abe3b, 0x9d93101d, 0x504b4adb, 0x45838822, 0x62126cc4, 0xf4198159, 0xf24a524c, 0x163fa3e9, 0x3c6d489e, 0xacef0dff, 0x73fc8fdd, 0x9d34fc09, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0xb8568ac2, 0x67a7ee09, 0x266abe3b, 0x9d93101d, 0x504b4adb, 0x45838822, 0x62126cc4, 0xf4198159, 0xf24a524c, 0x163fa3e9, 0x3c6d489e, 0xacef0dff, 0x73fc8fdd, 0x9d34fc09, 0x00000001, 0x400001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf017, 0x2fd1, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x5548cee0, 0x59a88eb4, 0x3624d775, 0x98fe9a19, 0x84d1b83f, 0xed2c476a, 0x046a6aea, 0x0c92fadb, 0xdff5abe1, 0x91a16e82, 0xbb0f8ba4, 0x87c1888c, 0xa2df958e, 0x6cebba03, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0x5548cee0, 0x59a88eb4, 0x3624d775, 0x98fe9a19, 0x84d1b83f, 0xed2c476a, 0x046a6aea, 0x0c92fadb, 0xdff5abe1, 0x91a16e82, 0xbb0f8ba4, 0x87c1888c, 0xa2df958e, 0x6cebba03, 0x00000001, 0x000001f0 },
},
// AND (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf403, 0x3ce5, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xddd90378, 0xc3a2891f, 0x3d5007a2, 0x0f0c0756, 0xbdc5c113, 0xeee78000, 0x90693126, 0x8763b349, 0xbf6814b4, 0x40160bf9, 0xfff4a26d, 0x16a11d59, 0x26b3b8cc, 0xeb09487f, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0xddd90378, 0xc3a2891f, 0x3d5007a2, 0x0f0c0756, 0xbdc5c113, 0xeee78000, 0x90693126, 0x8763b349, 0xbf6814b4, 0x40160bf9, 0xfff4a26d, 0x16a11d59, 0x00000200, 0xeb09487f, 0x00000001, 0x200001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf00a, 0x177d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xce4db266, 0x67f21be8, 0x0de0c290, 0x2615cfc5, 0x6e3c46cb, 0x44a52240, 0xb12e0470, 0x903e0182, 0x61c32a9a, 0x58bf0753, 0xa9b3c209, 0x68ec1f37, 0x9320a3c9, 0xab952fd9, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0xce4db266, 0x67f21be8, 0x0de0c290, 0x2615cfc5, 0x6e3c46cb, 0x44a52240, 0xb12e0470, 0x00310009, 0x61c32a9a, 0x58bf0753, 0xa9b3c209, 0x68ec1f37, 0x9320a3c9, 0xab952fd9, 0x00000001, 0xa00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf014, 0x2913, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x4257c8eb, 0xd9eaf199, 0xe9381b0a, 0x39fcb309, 0xb1f24181, 0xebb2b7e4, 0x73799a0f, 0xc70a2fc7, 0xe2af6496, 0xb9014f5b, 0xe22ff568, 0x12dd4afe, 0x6d8544ac, 0x9293d043, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x4257c8eb, 0xd9eaf199, 0xe9381b0a, 0x39fcb309, 0xb1f24181, 0xebb2b7e4, 0x73799a0f, 0xc70a2fc7, 0xe2af6496, 0x11000100, 0xe22ff568, 0x12dd4afe, 0x6d8544ac, 0x9293d043, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf004, 0x27c2, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x8d7ceb35, 0x000e9260, 0x6825b561, 0xbcf66952, 0x3fbc7775, 0xd5afaa83, 0xe4fde261, 0xa35fa71e, 0xbefc5c9f, 0x667d9163, 0x8c2543b0, 0xd8489b89, 0x661ffec5, 0x45ccdaa8, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x8d7ceb35, 0x000e9260, 0x6825b561, 0xbcf66952, 0x3fbc7775, 0xd5afaa83, 0xe4fde261, 0x02004200, 0xbefc5c9f, 0x667d9163, 0x8c2543b0, 0xd8489b89, 0x661ffec5, 0x45ccdaa8, 0x00000001, 0xd00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf008, 0x6ce5, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x78a2a638, 0x54ac2bd7, 0x60ad5509, 0x9c38b11f, 0x8dd109de, 0xd07aea77, 0xf5a0bcfc, 0xbcd81a17, 0x2f159ebd, 0xcc7e8454, 0x04621cce, 0xd0e9eca5, 0xb33f4ba6, 0x1e2bb5b2, 0x00000001, 0xf00001f0 },
FinalRegs = new uint[] { 0x78a2a638, 0x54ac2bd7, 0x60ad5509, 0x9c38b11f, 0x8dd109de, 0xd07aea77, 0xf5a0bcfc, 0xbcd81a17, 0x2f159ebd, 0xcc7e8454, 0x04621cce, 0xd0e9eca5, 0x07000000, 0x1e2bb5b2, 0x00000001, 0xf00001f0 },
},
// BIC (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf420, 0x6425, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x28c2ef44, 0x206bdfed, 0x30c780a9, 0x440ab4ab, 0x666fc882, 0x92a4aa1d, 0x3ceb6b36, 0xca757a75, 0xdf2f77b7, 0xae012305, 0x06b5c956, 0x0ff05e78, 0xad918973, 0x73778e28, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x28c2ef44, 0x206bdfed, 0x30c780a9, 0x440ab4ab, 0x28c2e504, 0x92a4aa1d, 0x3ceb6b36, 0xca757a75, 0xdf2f77b7, 0xae012305, 0x06b5c956, 0x0ff05e78, 0xad918973, 0x73778e28, 0x00000001, 0xe00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf430, 0x44ed, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x5cd96673, 0xa1c27ac5, 0xbb205490, 0xa844d844, 0x1e66662f, 0x0f259402, 0xbe81472f, 0x36d55b13, 0x02c6d2a2, 0xc39c31b1, 0x59b71936, 0xf1914252, 0xef8188b8, 0x0c18bea1, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0x5cd96673, 0xa1c27ac5, 0xbb205490, 0xa844d844, 0x5cd90073, 0x0f259402, 0xbe81472f, 0x36d55b13, 0x02c6d2a2, 0xc39c31b1, 0x59b71936, 0xf1914252, 0xef8188b8, 0x0c18bea1, 0x00000001, 0x100001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf038, 0x1334, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xe0afc0e0, 0x7ffd49d1, 0x6fe858fa, 0x7564882e, 0xaa895bf1, 0x725f4071, 0x612b9956, 0xb28fd700, 0xf0acd15c, 0xb62cf0bb, 0x1d9d5c1f, 0xdc3942a2, 0x9b3248ea, 0x3b7593ca, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0xe0afc0e0, 0x7ffd49d1, 0x6fe858fa, 0xf088d148, 0xaa895bf1, 0x725f4071, 0x612b9956, 0xb28fd700, 0xf0acd15c, 0xb62cf0bb, 0x1d9d5c1f, 0xdc3942a2, 0x9b3248ea, 0x3b7593ca, 0x00000001, 0xb00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf438, 0x51d7, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x75f070b0, 0x24e410c6, 0x128174fa, 0x04a10755, 0x6728fd35, 0xf6007f21, 0x0cb9efa3, 0x260e061c, 0xc5e02c94, 0x4aaa3354, 0x00796ab8, 0x897274d2, 0xe87dcffc, 0xa47bd3ab, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x75f070b0, 0xc5e02414, 0x128174fa, 0x04a10755, 0x6728fd35, 0xf6007f21, 0x0cb9efa3, 0x260e061c, 0xc5e02c94, 0x4aaa3354, 0x00796ab8, 0x897274d2, 0xe87dcffc, 0xa47bd3ab, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf438, 0x1db2, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x62dcbe9e, 0x55f42016, 0x6689f461, 0x31e32805, 0x1fc90a1e, 0x02e3a47f, 0xf236bafd, 0x65006290, 0x0065bd7f, 0xc1752579, 0x59528615, 0x6ef68c79, 0x138b8bb3, 0x0761d66c, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x62dcbe9e, 0x55f42016, 0x6689f461, 0x31e32805, 0x1fc90a1e, 0x02e3a47f, 0xf236bafd, 0x65006290, 0x0065bd7f, 0xc1752579, 0x59528615, 0x6ef68c79, 0x138b8bb3, 0x0061bd7f, 0x00000001, 0x000001f0 },
},
// MOV (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf45f, 0x5032, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x6ed98807, 0x536a9cb7, 0x79c2d5bb, 0xc2e9a860, 0x185b4e57, 0x77c1c99f, 0x99a24897, 0xc6cc4ea1, 0xe3d294a6, 0xb8e525ae, 0xca245840, 0x27943892, 0xa76ed6fe, 0xecbcffe8, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x00002c80, 0x536a9cb7, 0x79c2d5bb, 0xc2e9a860, 0x185b4e57, 0x77c1c99f, 0x99a24897, 0xc6cc4ea1, 0xe3d294a6, 0xb8e525ae, 0xca245840, 0x27943892, 0xa76ed6fe, 0xecbcffe8, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf04f, 0x23f9, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x7e6bf90e, 0x87533a8f, 0x29389323, 0x96a37f30, 0x63e6e58e, 0xb8bb21d0, 0x5bd9ae04, 0x26b7a586, 0xfa359510, 0x131a4e95, 0x5d0adb02, 0xa8148f64, 0xbfe74669, 0xea2cdf2d, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0x7e6bf90e, 0x87533a8f, 0x29389323, 0xf900f900, 0x63e6e58e, 0xb8bb21d0, 0x5bd9ae04, 0x26b7a586, 0xfa359510, 0x131a4e95, 0x5d0adb02, 0xa8148f64, 0xbfe74669, 0xea2cdf2d, 0x00000001, 0xb00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf45f, 0x5351, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd8b5d8b2, 0x7ae44f2b, 0xda909eb2, 0xdb2fe423, 0xb2486971, 0x23427a2c, 0x96c88749, 0xb88d6d78, 0x2f4aa092, 0xbf40760f, 0x88d72a3f, 0x88854e62, 0x8d459486, 0x82a8ba9f, 0x00000001, 0x300001f0 },
FinalRegs = new uint[] { 0xd8b5d8b2, 0x7ae44f2b, 0xda909eb2, 0x00003440, 0xb2486971, 0x23427a2c, 0x96c88749, 0xb88d6d78, 0x2f4aa092, 0xbf40760f, 0x88d72a3f, 0x88854e62, 0x8d459486, 0x82a8ba9f, 0x00000001, 0x100001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf45f, 0x207c, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x73063041, 0x038b5f4a, 0xf7e85421, 0xe935f110, 0x9a5c34de, 0xbc3dbed9, 0x1c57c517, 0x3294067f, 0x01cd78b5, 0xe7bfe428, 0x6e297fce, 0xccb2c833, 0x2e8bb930, 0xeb6e2004, 0x00000001, 0x300001f0 },
FinalRegs = new uint[] { 0x000fc000, 0x038b5f4a, 0xf7e85421, 0xe935f110, 0x9a5c34de, 0xbc3dbed9, 0x1c57c517, 0x3294067f, 0x01cd78b5, 0xe7bfe428, 0x6e297fce, 0xccb2c833, 0x2e8bb930, 0xeb6e2004, 0x00000001, 0x100001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf45f, 0x5073, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd0d531fe, 0xeb1676df, 0x0acf5912, 0x6061b3fe, 0xecac2ae2, 0x40075143, 0x88a47781, 0x3ecb7baa, 0x6aee3603, 0x53133f32, 0x1e891e57, 0x4d7f8f94, 0xd09c727a, 0x28a79c93, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0x00003cc0, 0xeb1676df, 0x0acf5912, 0x6061b3fe, 0xecac2ae2, 0x40075143, 0x88a47781, 0x3ecb7baa, 0x6aee3603, 0x53133f32, 0x1e891e57, 0x4d7f8f94, 0xd09c727a, 0x28a79c93, 0x00000001, 0x000001f0 },
},
// ORR (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf45c, 0x03c9, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xc7d9e145, 0xc2a6bd5b, 0x92c8ca0b, 0x1fde4d2f, 0xa4705c7f, 0x47559e93, 0x9f9d3e22, 0x7b3719c0, 0x3746ffc9, 0xa1476ae8, 0x88f45e36, 0x0fc7d2a7, 0xaa94b64c, 0xe9fee33b, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0xc7d9e145, 0xc2a6bd5b, 0x92c8ca0b, 0xaaf4b64c, 0xa4705c7f, 0x47559e93, 0x9f9d3e22, 0x7b3719c0, 0x3746ffc9, 0xa1476ae8, 0x88f45e36, 0x0fc7d2a7, 0xaa94b64c, 0xe9fee33b, 0x00000001, 0x900001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf441, 0x60ec, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x2262c23f, 0xf8ba9254, 0x2a870feb, 0xa66d2c1a, 0xa3bb8f6d, 0x2f754de2, 0xb3b0b9be, 0xc3cf59e8, 0xebaa6300, 0x22ea8a3d, 0xf3bcf0f4, 0xffb0aae8, 0x4982d5ab, 0x4c945119, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0xf8ba9774, 0xf8ba9254, 0x2a870feb, 0xa66d2c1a, 0xa3bb8f6d, 0x2f754de2, 0xb3b0b9be, 0xc3cf59e8, 0xebaa6300, 0x22ea8a3d, 0xf3bcf0f4, 0xffb0aae8, 0x4982d5ab, 0x4c945119, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf44c, 0x5343, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x844cd5c4, 0x5a244353, 0xd74ff677, 0x25eefc9f, 0xa040f56f, 0x06e237a6, 0x7ccb1c91, 0xc9aa6d32, 0xf9e18bd6, 0xc0780954, 0x955d8f60, 0xa9cb014e, 0x64d583e2, 0x3e50533a, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x844cd5c4, 0x5a244353, 0xd74ff677, 0x64d5b3e2, 0xa040f56f, 0x06e237a6, 0x7ccb1c91, 0xc9aa6d32, 0xf9e18bd6, 0xc0780954, 0x955d8f60, 0xa9cb014e, 0x64d583e2, 0x3e50533a, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf040, 0x48e2, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x24423eae, 0x40f7667e, 0x017f283e, 0x72887399, 0x063f4da0, 0x9b57a1c5, 0x5500c630, 0x6a304cac, 0xf9f10e9a, 0x02cdd193, 0x3f42bccd, 0x3c52ef2e, 0x15858a11, 0x25fd30bf, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x24423eae, 0x40f7667e, 0x017f283e, 0x72887399, 0x063f4da0, 0x9b57a1c5, 0x5500c630, 0x6a304cac, 0x75423eae, 0x02cdd193, 0x3f42bccd, 0x3c52ef2e, 0x15858a11, 0x25fd30bf, 0x00000001, 0xc00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf455, 0x1de0, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xc8c22d0e, 0x98a19d05, 0x61b4ea5e, 0x52f6f9a0, 0x2f8ceae4, 0x15649771, 0x61953174, 0x45b9d93f, 0x4e0629af, 0x30f43259, 0x863e8e5c, 0x3310b69e, 0xae5e5b9d, 0xf00e065a, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0xc8c22d0e, 0x98a19d05, 0x61b4ea5e, 0x52f6f9a0, 0x2f8ceae4, 0x15649771, 0x61953174, 0x45b9d93f, 0x4e0629af, 0x30f43259, 0x863e8e5c, 0x3310b69e, 0xae5e5b9d, 0x157c9771, 0x00000001, 0x100001f0 },
},
// MVN (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf46f, 0x1681, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xb1267a38, 0xe72b03aa, 0x50dc392a, 0xaff74b0d, 0xf83a17ba, 0xb8edf09d, 0x799df56d, 0x1ecbd371, 0xb4a74b9a, 0xe79f52fb, 0xbcec8b62, 0xbb0b01ea, 0x26d72e8c, 0x1d2ac349, 0x00000001, 0x900001f0 },
FinalRegs = new uint[] { 0xb1267a38, 0xe72b03aa, 0x50dc392a, 0xaff74b0d, 0xf83a17ba, 0xb8edf09d, 0xffefdfff, 0x1ecbd371, 0xb4a74b9a, 0xe79f52fb, 0xbcec8b62, 0xbb0b01ea, 0x26d72e8c, 0x1d2ac349, 0x00000001, 0x900001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf07f, 0x572f, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xa95387ad, 0x256c4ece, 0x32084d7a, 0x84935d58, 0x12f6880b, 0x3b386e47, 0xbeb69796, 0xdcf3fac5, 0xee2f9386, 0x25372541, 0x56499ba6, 0x06fa7586, 0xd114f908, 0x3442736e, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0xa95387ad, 0x256c4ece, 0x32084d7a, 0x84935d58, 0x12f6880b, 0x3b386e47, 0xbeb69796, 0xd43fffff, 0xee2f9386, 0x25372541, 0x56499ba6, 0x06fa7586, 0xd114f908, 0x3442736e, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf46f, 0x17e3, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd7f2d1e1, 0x1d12b22c, 0x2c26620c, 0xeadb8ead, 0x73560a2e, 0xf521b384, 0x4094f3d2, 0x17ed0f6f, 0x79d30498, 0x6d47211a, 0x8fdfef1d, 0xce6cbfa7, 0x75dc1c1b, 0x2ffd5d28, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0xd7f2d1e1, 0x1d12b22c, 0x2c26620c, 0xeadb8ead, 0x73560a2e, 0xf521b384, 0x4094f3d2, 0xffe39fff, 0x79d30498, 0x6d47211a, 0x8fdfef1d, 0xce6cbfa7, 0x75dc1c1b, 0x2ffd5d28, 0x00000001, 0x700001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf07f, 0x1431, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x4154dce7, 0x66c452e9, 0xff9bea1b, 0x228a4a5e, 0xe9fee66b, 0xddd7117f, 0x303cdcb6, 0x4bdf78a2, 0xfbcca92c, 0x2f628d24, 0x51816529, 0xcdea5042, 0x77a1e4a2, 0x8a745cb4, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0x4154dce7, 0x66c452e9, 0xff9bea1b, 0x228a4a5e, 0xffceffce, 0xddd7117f, 0x303cdcb6, 0x4bdf78a2, 0xfbcca92c, 0x2f628d24, 0x51816529, 0xcdea5042, 0x77a1e4a2, 0x8a745cb4, 0x00000001, 0xa00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf07f, 0x73ac, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd7b60274, 0x1ff3baba, 0xfdc8fa51, 0xcfacae9d, 0xd27a8214, 0xbbfb1abf, 0x3766111f, 0x89af2196, 0x4bd14cd6, 0x5af84659, 0xd279ed2f, 0x7abdf656, 0x868a6980, 0xd343d52a, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0xd7b60274, 0x1ff3baba, 0xfdc8fa51, 0xfea7ffff, 0xd27a8214, 0xbbfb1abf, 0x3766111f, 0x89af2196, 0x4bd14cd6, 0x5af84659, 0xd279ed2f, 0x7abdf656, 0x868a6980, 0xd343d52a, 0x00000001, 0x900001f0 },
},
// ORN (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf464, 0x0976, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x02e1c999, 0x40c2ff04, 0x16f00059, 0xd360cd62, 0xcb34f9d2, 0x303b434a, 0x53e0151f, 0x188b36bc, 0x84868958, 0xebad0ada, 0xdcd0cb74, 0x64bc056c, 0xd17a7256, 0xb71ddae3, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x02e1c999, 0x40c2ff04, 0x16f00059, 0xd360cd62, 0xcb34f9d2, 0x303b434a, 0x53e0151f, 0x188b36bc, 0x84868958, 0xff3dffff, 0xdcd0cb74, 0x64bc056c, 0xd17a7256, 0xb71ddae3, 0x00000001, 0x500001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf477, 0x3c66, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x71910713, 0xd17f8e75, 0x2652c7ac, 0xfad0527a, 0xc52b726d, 0x29e66793, 0xa1011225, 0x00c8ecc1, 0x48af4edd, 0x5c4e2e67, 0xc5393bd5, 0x702fcda1, 0x4549b1cf, 0x72d5a971, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x71910713, 0xd17f8e75, 0x2652c7ac, 0xfad0527a, 0xc52b726d, 0x29e66793, 0xa1011225, 0x00c8ecc1, 0x48af4edd, 0x5c4e2e67, 0xc5393bd5, 0x702fcda1, 0xfffcefff, 0x72d5a971, 0x00000001, 0x900001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf479, 0x1270, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x91060c85, 0x9b9c9033, 0x771ac325, 0x001e17c8, 0xb1adee43, 0xbaa9ec02, 0xf57f9f83, 0x3fed4e5c, 0x198cc3ea, 0x1a40edde, 0x6844391b, 0xa03319a0, 0xf741e11b, 0xc1892487, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x91060c85, 0x9b9c9033, 0xffc3ffff, 0x001e17c8, 0xb1adee43, 0xbaa9ec02, 0xf57f9f83, 0x3fed4e5c, 0x198cc3ea, 0x1a40edde, 0x6844391b, 0xa03319a0, 0xf741e11b, 0xc1892487, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf46f, 0x19d4, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x4fd5b2bd, 0x1c8f29ae, 0x12803c79, 0x93683874, 0xccd779c1, 0x6978c335, 0x06eb789d, 0xc8b74ef8, 0x51ca145a, 0x242d8047, 0x5036f51f, 0x13a4a4a2, 0x08818ae4, 0xe1687e67, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x4fd5b2bd, 0x1c8f29ae, 0x12803c79, 0x93683874, 0xccd779c1, 0x6978c335, 0x06eb789d, 0xc8b74ef8, 0x51ca145a, 0xffe57fff, 0x5036f51f, 0x13a4a4a2, 0x08818ae4, 0xe1687e67, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf07f, 0x614f, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x83c9ef5a, 0xb5933c7e, 0x2dc23d71, 0x5723ae27, 0x1218bc2c, 0x456f3dbd, 0xf6ee7d22, 0xde4df878, 0x3e800973, 0x39c4c131, 0x0676384d, 0xef62a558, 0x2acc92f2, 0x9cd71aa1, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0x83c9ef5a, 0xf30fffff, 0x2dc23d71, 0x5723ae27, 0x1218bc2c, 0x456f3dbd, 0xf6ee7d22, 0xde4df878, 0x3e800973, 0x39c4c131, 0x0676384d, 0xef62a558, 0x2acc92f2, 0x9cd71aa1, 0x00000001, 0x900001f0 },
},
// TEQ (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf49b, 0x2fe4, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xc87047c3, 0x99001273, 0xa963adc7, 0xaba3d1a1, 0x4b9c13a0, 0xc42566ba, 0xee0b7ab1, 0x3e4423ec, 0x5d874e97, 0xfffb5799, 0xdb88f462, 0xbdc4a9e2, 0x3933e52b, 0xe1839111, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0xc87047c3, 0x99001273, 0xa963adc7, 0xaba3d1a1, 0x4b9c13a0, 0xc42566ba, 0xee0b7ab1, 0x3e4423ec, 0x5d874e97, 0xfffb5799, 0xdb88f462, 0xbdc4a9e2, 0x3933e52b, 0xe1839111, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf09b, 0x0f59, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x6d2c2ac7, 0xdd2b59f4, 0x3fc013f4, 0x567e744e, 0xc4feb096, 0x188454f3, 0xae13338b, 0x66a0a40b, 0xac995945, 0x7e27f097, 0x547cbd54, 0xd2abf0ab, 0x02c08b3e, 0xe6d1283f, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x6d2c2ac7, 0xdd2b59f4, 0x3fc013f4, 0x567e744e, 0xc4feb096, 0x188454f3, 0xae13338b, 0x66a0a40b, 0xac995945, 0x7e27f097, 0x547cbd54, 0xd2abf0ab, 0x02c08b3e, 0xe6d1283f, 0x00000001, 0x900001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf494, 0x6f3d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x16342d21, 0xff794fb0, 0x513ba230, 0x7b9e4b2b, 0x9a2d1ba9, 0xebce0dae, 0xe792f2b8, 0xf4932236, 0x0bcd9542, 0x12bcab94, 0x0110b845, 0xdde237b0, 0xa401d5b9, 0xc3162f6d, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x16342d21, 0xff794fb0, 0x513ba230, 0x7b9e4b2b, 0x9a2d1ba9, 0xebce0dae, 0xe792f2b8, 0xf4932236, 0x0bcd9542, 0x12bcab94, 0x0110b845, 0xdde237b0, 0xa401d5b9, 0xc3162f6d, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf09c, 0x6f59, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x8d9e2002, 0xfa519294, 0x700740d6, 0x29220c73, 0x8f0ad8b2, 0x6ce9d5e8, 0x12f9da7a, 0x286a9813, 0x2be49d73, 0x16241aa1, 0xe096f43b, 0x1fd0d3e2, 0x31791bb5, 0xa4943f4e, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x8d9e2002, 0xfa519294, 0x700740d6, 0x29220c73, 0x8f0ad8b2, 0x6ce9d5e8, 0x12f9da7a, 0x286a9813, 0x2be49d73, 0x16241aa1, 0xe096f43b, 0x1fd0d3e2, 0x31791bb5, 0xa4943f4e, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf094, 0x6f35, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x222e0e7c, 0xa89d1fdf, 0xa7d67bc3, 0x658e1ee9, 0x10b41780, 0x5cd566a4, 0xce03a58a, 0x63fb9a9e, 0x4f5cb2bd, 0x14e72619, 0x296a9bd5, 0xbf7b1fb1, 0x705a45cc, 0xba8540ae, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x222e0e7c, 0xa89d1fdf, 0xa7d67bc3, 0x658e1ee9, 0x10b41780, 0x5cd566a4, 0xce03a58a, 0x63fb9a9e, 0x4f5cb2bd, 0x14e72619, 0x296a9bd5, 0xbf7b1fb1, 0x705a45cc, 0xba8540ae, 0x00000001, 0x000001f0 },
},
// EOR (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf496, 0x54fb, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x6267728b, 0xc834f7c7, 0xa136a1d6, 0xfd9533e9, 0x096db729, 0x8fff8a73, 0x6a45348e, 0xd52111ed, 0xa5640aff, 0xa4cf82a6, 0x5ab70b5c, 0x5b3c4563, 0xf1a91ab7, 0x5718fdd1, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0x6267728b, 0xc834f7c7, 0xa136a1d6, 0xfd9533e9, 0x6a452bee, 0x8fff8a73, 0x6a45348e, 0xd52111ed, 0xa5640aff, 0xa4cf82a6, 0x5ab70b5c, 0x5b3c4563, 0xf1a91ab7, 0x5718fdd1, 0x00000001, 0x100001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf08a, 0x339d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xbf1e6da6, 0x2c10408a, 0xe961ddde, 0x5add8306, 0xc266064d, 0xa79569e1, 0x945c28ed, 0xb996f578, 0x68082b6e, 0x14cdd2c7, 0x7d0cc6a2, 0x8d6edfbf, 0x9151e24c, 0x63eaee32, 0x00000001, 0x300001f0 },
FinalRegs = new uint[] { 0xbf1e6da6, 0x2c10408a, 0xe961ddde, 0xe0915b3f, 0xc266064d, 0xa79569e1, 0x945c28ed, 0xb996f578, 0x68082b6e, 0x14cdd2c7, 0x7d0cc6a2, 0x8d6edfbf, 0x9151e24c, 0x63eaee32, 0x00000001, 0x300001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf490, 0x27d8, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd6826a86, 0x39aa35f5, 0x2a8a913e, 0xd9dbf560, 0xcb1a9957, 0xe6779d2f, 0x0eeab3f9, 0xa463d4c2, 0xb3187660, 0xa51778c3, 0x73817179, 0x6d6dae92, 0x864a3e80, 0x43d8f181, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0xd6826a86, 0x39aa35f5, 0x2a8a913e, 0xd9dbf560, 0xcb1a9957, 0xe6779d2f, 0x0eeab3f9, 0xd684aa86, 0xb3187660, 0xa51778c3, 0x73817179, 0x6d6dae92, 0x864a3e80, 0x43d8f181, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf485, 0x3d32, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x063885c0, 0xa183a44d, 0x5cb2f961, 0xe44b8670, 0x8ec25495, 0xb8f5a831, 0x1c2fecb4, 0xfc15fcff, 0x28dd902e, 0xf0c875f4, 0x0af03bb5, 0xefe4ba8b, 0x10e57000, 0x4cd51767, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0x063885c0, 0xa183a44d, 0x5cb2f961, 0xe44b8670, 0x8ec25495, 0xb8f5a831, 0x1c2fecb4, 0xfc15fcff, 0x28dd902e, 0xf0c875f4, 0x0af03bb5, 0xefe4ba8b, 0x10e57000, 0xb8f76031, 0x00000001, 0xb00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf095, 0x58e8, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x5a60610b, 0x4d178413, 0x3b12edd0, 0x23afc7fc, 0x47f0647d, 0x327bd294, 0x52351d80, 0x36733323, 0x490a0d2a, 0x75d5888c, 0x9b45f4e6, 0x89ebf7dc, 0xd278dd78, 0x1b9b0bbd, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0x5a60610b, 0x4d178413, 0x3b12edd0, 0x23afc7fc, 0x47f0647d, 0x327bd294, 0x52351d80, 0x36733323, 0x2f7bd294, 0x75d5888c, 0x9b45f4e6, 0x89ebf7dc, 0xd278dd78, 0x1b9b0bbd, 0x00000001, 0x000001f0 },
},
// CMN (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf514, 0x6f12, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xec864396, 0xe2f483b8, 0x18df08c9, 0xae7780ba, 0xd16bc913, 0x892037de, 0x84a3589e, 0x3a468960, 0x004f92e4, 0x6fd793c2, 0x81b048c6, 0xe044e7cf, 0x2199ccda, 0x4667415d, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0xec864396, 0xe2f483b8, 0x18df08c9, 0xae7780ba, 0xd16bc913, 0x892037de, 0x84a3589e, 0x3a468960, 0x004f92e4, 0x6fd793c2, 0x81b048c6, 0xe044e7cf, 0x2199ccda, 0x4667415d, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf517, 0x2f38, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x154548b0, 0x28aed64c, 0x533306b3, 0x8eace432, 0x9a6523f1, 0x22b08ccb, 0xe7fceaf6, 0x45429c2c, 0xf58378c1, 0x0ef49416, 0x88dbd472, 0xf6a35b6c, 0x46b19364, 0x52e4982d, 0x00000001, 0x900001f0 },
FinalRegs = new uint[] { 0x154548b0, 0x28aed64c, 0x533306b3, 0x8eace432, 0x9a6523f1, 0x22b08ccb, 0xe7fceaf6, 0x45429c2c, 0xf58378c1, 0x0ef49416, 0x88dbd472, 0xf6a35b6c, 0x46b19364, 0x52e4982d, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf116, 0x7fe2, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x30b90186, 0xec7b038f, 0xcb392feb, 0x10c09c2f, 0x8619521d, 0xcf8d7075, 0x108f8f49, 0x6e44275d, 0x1728faed, 0xf2a0b2a4, 0x783cf97f, 0x201d6d0b, 0x317f276d, 0x5a7186e2, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x30b90186, 0xec7b038f, 0xcb392feb, 0x10c09c2f, 0x8619521d, 0xcf8d7075, 0x108f8f49, 0x6e44275d, 0x1728faed, 0xf2a0b2a4, 0x783cf97f, 0x201d6d0b, 0x317f276d, 0x5a7186e2, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf51b, 0x7f4a, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xedd3c03d, 0xd7cce5a2, 0xfc40b40a, 0x6a9c96f3, 0x40ca8c2d, 0xaa2973e1, 0xd7953408, 0xfa11d2df, 0x7cec28c2, 0x4e523380, 0x007a4ac6, 0x03890c29, 0xd1495b3e, 0xdf1af969, 0x00000001, 0x500001f0 },
FinalRegs = new uint[] { 0xedd3c03d, 0xd7cce5a2, 0xfc40b40a, 0x6a9c96f3, 0x40ca8c2d, 0xaa2973e1, 0xd7953408, 0xfa11d2df, 0x7cec28c2, 0x4e523380, 0x007a4ac6, 0x03890c29, 0xd1495b3e, 0xdf1af969, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf11c, 0x5f9c, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd8c0c360, 0xd50bcc87, 0xe265e8b2, 0xca49cc71, 0xa6bb11c8, 0x13649388, 0x034a4c8c, 0xa3b4c570, 0x014d32ac, 0x1847d102, 0x7fc3678d, 0xb0e0f469, 0x9508a619, 0x2a2372e0, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0xd8c0c360, 0xd50bcc87, 0xe265e8b2, 0xca49cc71, 0xa6bb11c8, 0x13649388, 0x034a4c8c, 0xa3b4c570, 0x014d32ac, 0x1847d102, 0x7fc3678d, 0xb0e0f469, 0x9508a619, 0x2a2372e0, 0x00000001, 0x800001f0 },
},
// ADD (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf10b, 0x00e0, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xadc2fe68, 0xa8a14518, 0x5baf5e87, 0x17e2b502, 0x638227c2, 0xba11428f, 0x98c5b963, 0x5b9cbcd3, 0xb4c11f97, 0x0ca6832e, 0xea26efa6, 0x7bb19ec8, 0x8ea04a89, 0x62d597c2, 0x00000001, 0x300001f0 },
FinalRegs = new uint[] { 0x7bb19fa8, 0xa8a14518, 0x5baf5e87, 0x17e2b502, 0x638227c2, 0xba11428f, 0x98c5b963, 0x5b9cbcd3, 0xb4c11f97, 0x0ca6832e, 0xea26efa6, 0x7bb19ec8, 0x8ea04a89, 0x62d597c2, 0x00000001, 0x300001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf114, 0x7b41, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x9366f694, 0x02670e58, 0x6f3e74b8, 0x567d3e30, 0xeebb29c4, 0xc25ce8e6, 0x942b94c8, 0xc7dccdd9, 0xccfe17a9, 0xeacc4db1, 0xbbbc0fde, 0x248b7093, 0x7f66c92d, 0xfc063cb6, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x9366f694, 0x02670e58, 0x6f3e74b8, 0x567d3e30, 0xeebb29c4, 0xc25ce8e6, 0x942b94c8, 0xc7dccdd9, 0xccfe17a9, 0xeacc4db1, 0xbbbc0fde, 0xf1bf29c4, 0x7f66c92d, 0xfc063cb6, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf51c, 0x21d1, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x2b53ae1e, 0x733046c3, 0xbcc33a3a, 0x2f7bbd50, 0xed2a39f2, 0xfee631ec, 0xeb6d3bc3, 0x9f9b502d, 0x30d20f7b, 0xdc75211b, 0xdb234e2b, 0x85008c86, 0x43beb508, 0x6a8303d5, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x2b53ae1e, 0x43c53d08, 0xbcc33a3a, 0x2f7bbd50, 0xed2a39f2, 0xfee631ec, 0xeb6d3bc3, 0x9f9b502d, 0x30d20f7b, 0xdc75211b, 0xdb234e2b, 0x85008c86, 0x43beb508, 0x6a8303d5, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf513, 0x22e8, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xbb3b52c1, 0x40ff59f3, 0x05ca09c5, 0x440114be, 0xec3a4022, 0x0ff93d8c, 0x38868879, 0x824d36d8, 0xf513a9d8, 0xf1d0ad5a, 0xc453fdd8, 0xe3dc8d52, 0x1fc5a9ef, 0x809dbe9b, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0xbb3b52c1, 0x40ff59f3, 0x440854be, 0x440114be, 0xec3a4022, 0x0ff93d8c, 0x38868879, 0x824d36d8, 0xf513a9d8, 0xf1d0ad5a, 0xc453fdd8, 0xe3dc8d52, 0x1fc5a9ef, 0x809dbe9b, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf518, 0x68c7, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xf9c00a78, 0xf47ee408, 0xdc31e40b, 0x167902da, 0x03b23f2f, 0x6d41efdc, 0x9cb99b17, 0x21bfbf63, 0x9fbe8105, 0x250087d0, 0xe0588965, 0x0f0f669c, 0x2ed04b37, 0xc65c6e2e, 0x00000001, 0x100001f0 },
FinalRegs = new uint[] { 0xf9c00a78, 0xf47ee408, 0xdc31e40b, 0x167902da, 0x03b23f2f, 0x6d41efdc, 0x9cb99b17, 0x21bfbf63, 0x9fbe873d, 0x250087d0, 0xe0588965, 0x0f0f669c, 0x2ed04b37, 0xc65c6e2e, 0x00000001, 0x800001f0 },
},
// ADC (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf54d, 0x379a, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x09eb57e5, 0xc9981095, 0x94b0bf26, 0x27080c39, 0x9fba115a, 0xde0e1533, 0xaa5916aa, 0x1bfc2313, 0x32a96f13, 0x5b8f2d6c, 0x9098dcf2, 0x86143a3f, 0x5c004908, 0xd233cd08, 0x00000001, 0x300001f0 },
FinalRegs = new uint[] { 0x09eb57e5, 0xc9981095, 0x94b0bf26, 0x27080c39, 0x9fba115a, 0xde0e1533, 0xaa5916aa, 0xd2350109, 0x32a96f13, 0x5b8f2d6c, 0x9098dcf2, 0x86143a3f, 0x5c004908, 0xd233cd08, 0x00000001, 0x300001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf149, 0x3a77, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xe32aaf45, 0x05fe0eac, 0x9c782c15, 0x9301164b, 0xa2f59aea, 0xe6b2618b, 0xfceb237a, 0xcfeb98bd, 0xaaa75e8d, 0xbb57f750, 0xd282f40d, 0xa181d4d7, 0x93313b48, 0x9a64c67f, 0x00000001, 0xf00001f0 },
FinalRegs = new uint[] { 0xe32aaf45, 0x05fe0eac, 0x9c782c15, 0x9301164b, 0xa2f59aea, 0xe6b2618b, 0xfceb237a, 0xcfeb98bd, 0xaaa75e8d, 0xbb57f750, 0x32cf6ec8, 0xa181d4d7, 0x93313b48, 0x9a64c67f, 0x00000001, 0xf00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf549, 0x57c8, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x67da941e, 0x5d744410, 0x1f93bf8f, 0xb52727e0, 0x77ce10fe, 0xe7a40291, 0x40ac5a1f, 0x127e801f, 0x68233546, 0xdbe8086f, 0x82b65e68, 0xcf35c09b, 0x8846e02d, 0x5fd54256, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x67da941e, 0x5d744410, 0x1f93bf8f, 0xb52727e0, 0x77ce10fe, 0xe7a40291, 0x40ac5a1f, 0xdbe82170, 0x68233546, 0xdbe8086f, 0x82b65e68, 0xcf35c09b, 0x8846e02d, 0x5fd54256, 0x00000001, 0x200001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf15c, 0x1649, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x86cf07b1, 0x1c86e00f, 0x8dc39789, 0xe8fafb40, 0xb837bf22, 0xe9c2c765, 0xb9e8b84b, 0xdbc9663e, 0x979b81da, 0xfb7a5636, 0x9012981d, 0xf52ec47c, 0xf98f6294, 0xaf70ff24, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x86cf07b1, 0x1c86e00f, 0x8dc39789, 0xe8fafb40, 0xb837bf22, 0xe9c2c765, 0xf9d862de, 0xdbc9663e, 0x979b81da, 0xfb7a5636, 0x9012981d, 0xf52ec47c, 0xf98f6294, 0xaf70ff24, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf144, 0x6ab6, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x151549e7, 0xbdfa6ced, 0x47ba5025, 0xaba24048, 0x17c38ef8, 0xf92095ec, 0xdccd5b6f, 0xcb3878a5, 0x30d25594, 0x94886d84, 0xaec74633, 0xbe39725f, 0x439d8ef1, 0xcd66a204, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x151549e7, 0xbdfa6ced, 0x47ba5025, 0xaba24048, 0x17c38ef8, 0xf92095ec, 0xdccd5b6f, 0xcb3878a5, 0x30d25594, 0x94886d84, 0x1d738ef8, 0xbe39725f, 0x439d8ef1, 0xcd66a204, 0x00000001, 0x000001f0 },
},
// SBC (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf565, 0x3beb, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x23efd21b, 0x78e2f658, 0x37a4e044, 0x8feab92a, 0x9795995f, 0x66c7ddab, 0x1c29040f, 0x10034172, 0x2eede540, 0x961c1400, 0x34cf45b9, 0xdb736f38, 0xd601c8ed, 0x99a714af, 0x00000001, 0xf00001f0 },
FinalRegs = new uint[] { 0x23efd21b, 0x78e2f658, 0x37a4e044, 0x8feab92a, 0x9795995f, 0x66c7ddab, 0x1c29040f, 0x10034172, 0x2eede540, 0x961c1400, 0x34cf45b9, 0x66c607ab, 0xd601c8ed, 0x99a714af, 0x00000001, 0xf00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf172, 0x1b0d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x596b63ec, 0xb659c798, 0x300ca58e, 0x52200fa5, 0x0db74ebe, 0x01e5b394, 0xed83d480, 0x1a524b19, 0x593d9bd1, 0x1152a751, 0xf3e1cb1c, 0xfb9392e3, 0x08fc2cd9, 0xc3910cf3, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x596b63ec, 0xb659c798, 0x300ca58e, 0x52200fa5, 0x0db74ebe, 0x01e5b394, 0xed83d480, 0x1a524b19, 0x593d9bd1, 0x1152a751, 0xf3e1cb1c, 0x2fffa580, 0x08fc2cd9, 0xc3910cf3, 0x00000001, 0x200001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf57c, 0x14da, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x5eab5df9, 0x3cfdd390, 0xcfd20097, 0xc8986688, 0xa714c17c, 0xc9eee620, 0x6626498e, 0x2de48d3c, 0xc27c794f, 0xf7d0c67f, 0x75b6b9d9, 0xbaf9f630, 0x7bd89fad, 0xe5a2e298, 0x00000001, 0xe00001f0 },
FinalRegs = new uint[] { 0x5eab5df9, 0x3cfdd390, 0xcfd20097, 0xc8986688, 0x7bbd5fad, 0xc9eee620, 0x6626498e, 0x2de48d3c, 0xc27c794f, 0xf7d0c67f, 0x75b6b9d9, 0xbaf9f630, 0x7bd89fad, 0xe5a2e298, 0x00000001, 0x200001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf57a, 0x6bbf, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xaee56760, 0xa9f9b7d4, 0x9dd85a8c, 0x4c8cea6b, 0x7807b53d, 0xd1349b90, 0xcf320f62, 0x7af6d0c9, 0xc61fac5f, 0x23b43bbd, 0xef7466b3, 0x98e322a8, 0x1e10ae81, 0xb6987dcc, 0x00000001, 0xa00001f0 },
FinalRegs = new uint[] { 0xaee56760, 0xa9f9b7d4, 0x9dd85a8c, 0x4c8cea6b, 0x7807b53d, 0xd1349b90, 0xcf320f62, 0x7af6d0c9, 0xc61fac5f, 0x23b43bbd, 0xef7466b3, 0xef7460bb, 0x1e10ae81, 0xb6987dcc, 0x00000001, 0xa00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf171, 0x47e8, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x4164d035, 0x72eecb21, 0xbb63329c, 0x8883a249, 0x230b524b, 0x40c059ae, 0x529e2950, 0xd0f7b958, 0xae900a4a, 0xa5a3f2b5, 0xe68da7f3, 0x68fececb, 0x91a2f476, 0x3986b8a0, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0x4164d035, 0x72eecb21, 0xbb63329c, 0x8883a249, 0x230b524b, 0x40c059ae, 0x529e2950, 0xfeeecb20, 0xae900a4a, 0xa5a3f2b5, 0xe68da7f3, 0x68fececb, 0x91a2f476, 0x3986b8a0, 0x00000001, 0x800001f0 },
},
// CMP (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5ba, 0x7f0c, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x32876eff, 0x3127746f, 0x25274f4b, 0x50ba4fa5, 0xa3013fb5, 0x4985e2cb, 0x43dad09c, 0xfb6e47f2, 0x673ee708, 0x3beee172, 0x4866bb83, 0x9368060a, 0x565ecf8e, 0xecc22394, 0x00000001, 0xc00001f0 },
FinalRegs = new uint[] { 0x32876eff, 0x3127746f, 0x25274f4b, 0x50ba4fa5, 0xa3013fb5, 0x4985e2cb, 0x43dad09c, 0xfb6e47f2, 0x673ee708, 0x3beee172, 0x4866bb83, 0x9368060a, 0x565ecf8e, 0xecc22394, 0x00000001, 0x200001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf1b4, 0x5f0c, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xabb3ffca, 0x7dbdda85, 0xe413a0d4, 0xf2ea8958, 0x81be2593, 0x8b0997e0, 0x5319660b, 0xd4edc3d0, 0x4b147c71, 0xa60a6a5f, 0x9984a94a, 0xbabe5540, 0x24df8017, 0x1e97e9f5, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0xabb3ffca, 0x7dbdda85, 0xe413a0d4, 0xf2ea8958, 0x81be2593, 0x8b0997e0, 0x5319660b, 0xd4edc3d0, 0x4b147c71, 0xa60a6a5f, 0x9984a94a, 0xbabe5540, 0x24df8017, 0x1e97e9f5, 0x00000001, 0x300001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5b1, 0x0f4b, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xf6edbf76, 0xd3f53e21, 0x37679835, 0x6af58147, 0x143dd6be, 0x4f6339d1, 0x0261fa88, 0x38fe033f, 0x1b503fb3, 0x802af22b, 0x22901e74, 0xae61d40e, 0xe1e850ee, 0xe353701c, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0xf6edbf76, 0xd3f53e21, 0x37679835, 0x6af58147, 0x143dd6be, 0x4f6339d1, 0x0261fa88, 0x38fe033f, 0x1b503fb3, 0x802af22b, 0x22901e74, 0xae61d40e, 0xe1e850ee, 0xe353701c, 0x00000001, 0xa00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5b2, 0x7f57, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x350b2e14, 0xcc603c9e, 0xa7a56491, 0x1f4fe90b, 0x6bb14aba, 0x325154ef, 0xc7655249, 0xe1a6077b, 0x145fc2f0, 0x21e0bc5e, 0x18275d8b, 0x0d8f37f0, 0xfdb56518, 0x405f5649, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x350b2e14, 0xcc603c9e, 0xa7a56491, 0x1f4fe90b, 0x6bb14aba, 0x325154ef, 0xc7655249, 0xe1a6077b, 0x145fc2f0, 0x21e0bc5e, 0x18275d8b, 0x0d8f37f0, 0xfdb56518, 0x405f5649, 0x00000001, 0xa00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf1b7, 0x0fd0, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x5a7f551b, 0x624d7cb7, 0xdc3e4dab, 0xd242610e, 0x8b7213db, 0x3c4f81df, 0x353e713e, 0x0ffdfd5c, 0xe56efdf9, 0x59330bc2, 0x1b91689c, 0x5497152e, 0x7ce02ab7, 0x0127aeca, 0x00000001, 0xd00001f0 },
FinalRegs = new uint[] { 0x5a7f551b, 0x624d7cb7, 0xdc3e4dab, 0xd242610e, 0x8b7213db, 0x3c4f81df, 0x353e713e, 0x0ffdfd5c, 0xe56efdf9, 0x59330bc2, 0x1b91689c, 0x5497152e, 0x7ce02ab7, 0x0127aeca, 0x00000001, 0x200001f0 },
},
// SUB (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5a6, 0x2902, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x688a6dd6, 0xcabb9832, 0xa187c464, 0xe4474634, 0x19316c88, 0x8b99d147, 0xd67bc441, 0x48cfa0cf, 0x4cd8b792, 0x9593d34d, 0x66b5a570, 0x9065cc35, 0x6ddf1e6f, 0xd49a2985, 0x00000001, 0xf00001f0 },
FinalRegs = new uint[] { 0x688a6dd6, 0xcabb9832, 0xa187c464, 0xe4474634, 0x19316c88, 0x8b99d147, 0xd67bc441, 0x48cfa0cf, 0x4cd8b792, 0xd673a441, 0x66b5a570, 0x9065cc35, 0x6ddf1e6f, 0xd49a2985, 0x00000001, 0xf00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf1a5, 0x4730, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x69e8d900, 0x3ca9d66e, 0x91788f4e, 0x6e821399, 0xd710747f, 0xc8e72a37, 0xf9f9702f, 0x8e689c3f, 0x87ef1e3c, 0xc8270c3e, 0xd76f0d87, 0x5482900c, 0xec43f474, 0x72617560, 0x00000001, 0x000001f0 },
FinalRegs = new uint[] { 0x69e8d900, 0x3ca9d66e, 0x91788f4e, 0x6e821399, 0xd710747f, 0xc8e72a37, 0xf9f9702f, 0x18e72a37, 0x87ef1e3c, 0xc8270c3e, 0xd76f0d87, 0x5482900c, 0xec43f474, 0x72617560, 0x00000001, 0x000001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5bd, 0x7d6b, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x56f27741, 0xdf3a0328, 0x49864f87, 0xd8b84caa, 0xd7a4cc2b, 0x85467faf, 0x6e972a47, 0xc2440b53, 0xa56fc6fa, 0xe86c3322, 0x19e1532d, 0x2984be63, 0xd7302738, 0xbf00369c, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0x56f27741, 0xdf3a0328, 0x49864f87, 0xd8b84caa, 0xd7a4cc2b, 0x85467faf, 0x6e972a47, 0xc2440b53, 0xa56fc6fa, 0xe86c3322, 0x19e1532d, 0x2984be63, 0xd7302738, 0xbf0032f0, 0x00000001, 0xa00001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5aa, 0x048c, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xc48ce68c, 0x33c654cc, 0xa31ea382, 0x398c4095, 0xfff680a5, 0x5886b5f4, 0xb1debf0b, 0x8bd529bb, 0x1354ba05, 0xcf80960a, 0x18582cbe, 0x37ca8996, 0x08f95e3c, 0xc87fdb04, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0xc48ce68c, 0x33c654cc, 0xa31ea382, 0x398c4095, 0x18122cbe, 0x5886b5f4, 0xb1debf0b, 0x8bd529bb, 0x1354ba05, 0xcf80960a, 0x18582cbe, 0x37ca8996, 0x08f95e3c, 0xc87fdb04, 0x00000001, 0x200001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5ba, 0x13aa, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xd2de6567, 0x993624bf, 0xcfbd492f, 0x7b922424, 0x9fa01912, 0x04225225, 0x3a812a6d, 0xe62792b8, 0xb47cee9a, 0x5694288e, 0x6c669666, 0x213701a6, 0xe423ad2d, 0xc7d5362b, 0x00000001, 0xb00001f0 },
FinalRegs = new uint[] { 0xd2de6567, 0x993624bf, 0xcfbd492f, 0x6c515666, 0x9fa01912, 0x04225225, 0x3a812a6d, 0xe62792b8, 0xb47cee9a, 0x5694288e, 0x6c669666, 0x213701a6, 0xe423ad2d, 0xc7d5362b, 0x00000001, 0x200001f0 },
},
// RSB (imm)
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5dc, 0x767d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x8496100e, 0x93007a60, 0x0d33d3dc, 0xd932c4e1, 0x6e05ad8d, 0xde3cc68e, 0x74400ff8, 0xce309ee7, 0x188e0ebd, 0xe10837ab, 0x6b2534e2, 0x280add20, 0x3adc0489, 0x8ef32355, 0x00000001, 0x600001f0 },
FinalRegs = new uint[] { 0x8496100e, 0x93007a60, 0x0d33d3dc, 0xd932c4e1, 0x6e05ad8d, 0xde3cc68e, 0xc523ff6b, 0xce309ee7, 0x188e0ebd, 0xe10837ab, 0x6b2534e2, 0x280add20, 0x3adc0489, 0x8ef32355, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf1dc, 0x377d, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xc5d7fe20, 0xade81daf, 0xba65ccf8, 0xa101ee00, 0x3a2b70d9, 0xc90238d9, 0xc3b54049, 0x436bf83f, 0x99c96b58, 0xd134cb19, 0x4de47e7f, 0x6a175e2d, 0xd9e49229, 0x174d24ac, 0x00000001, 0x400001f0 },
FinalRegs = new uint[] { 0xc5d7fe20, 0xade81daf, 0xba65ccf8, 0xa101ee00, 0x3a2b70d9, 0xc90238d9, 0xc3b54049, 0xa398eb54, 0x99c96b58, 0xd134cb19, 0x4de47e7f, 0x6a175e2d, 0xd9e49229, 0x174d24ac, 0x00000001, 0x900001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5c5, 0x34bd, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0xcea4f214, 0xdc15a8f8, 0xd22be9ef, 0x42c400c5, 0x2fd1fc9b, 0xca724b52, 0x5582071d, 0xd01b7816, 0xa4f5a435, 0xcfd50db5, 0x24e0c80b, 0x7b52178d, 0x11cd0449, 0xd6daa84a, 0x00000001, 0x800001f0 },
FinalRegs = new uint[] { 0xcea4f214, 0xdc15a8f8, 0xd22be9ef, 0x42c400c5, 0x358f2eae, 0xca724b52, 0x5582071d, 0xd01b7816, 0xa4f5a435, 0xcfd50db5, 0x24e0c80b, 0x7b52178d, 0x11cd0449, 0xd6daa84a, 0x00000001, 0x800001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf1ce, 0x7846, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x3c676ff3, 0x511ea0cb, 0x15e79c80, 0x51a3a8c1, 0x535cc233, 0x6ae729a3, 0x4e5726da, 0x81260fb9, 0x24dd423a, 0x9e81d6c0, 0x812b3bd1, 0x55bd0f44, 0x1871ec65, 0x87087126, 0x00000001, 0x200001f0 },
FinalRegs = new uint[] { 0x3c676ff3, 0x511ea0cb, 0x15e79c80, 0x51a3a8c1, 0x535cc233, 0x6ae729a3, 0x4e5726da, 0x81260fb9, 0x0317ffff, 0x9e81d6c0, 0x812b3bd1, 0x55bd0f44, 0x1871ec65, 0x87087126, 0x00000001, 0x200001f0 },
},
new PrecomputedThumbTestCase()
{
Instructions = new ushort[] { 0xf5c5, 0x2418, 0x4770, 0xe7fe },
StartRegs = new uint[] { 0x2bb00694, 0x1c56a4c0, 0xc5cc4a3e, 0xc627c1ab, 0x4e4a8dfc, 0x1f3d71a4, 0x897d57b8, 0x0d4a7208, 0x433b7b88, 0xaaf24fd6, 0x2438f5f8, 0x9875e64a, 0xda475f22, 0x66d5e2e7, 0x00000001, 0x700001f0 },
FinalRegs = new uint[] { 0x2bb00694, 0x1c56a4c0, 0xc5cc4a3e, 0xc627c1ab, 0xe0cc0e5c, 0x1f3d71a4, 0x897d57b8, 0x0d4a7208, 0x433b7b88, 0xaaf24fd6, 0x2438f5f8, 0x9875e64a, 0xda475f22, 0x66d5e2e7, 0x00000001, 0x700001f0 },
},
};
} }
} }

View File

@@ -73,6 +73,7 @@ namespace Ryujinx.Ui.Windows
[GUI] ToggleButton _lStick; [GUI] ToggleButton _lStick;
[GUI] CheckButton _invertLStickX; [GUI] CheckButton _invertLStickX;
[GUI] CheckButton _invertLStickY; [GUI] CheckButton _invertLStickY;
[GUI] CheckButton _rotateL90CW;
[GUI] ToggleButton _lStickUp; [GUI] ToggleButton _lStickUp;
[GUI] ToggleButton _lStickDown; [GUI] ToggleButton _lStickDown;
[GUI] ToggleButton _lStickLeft; [GUI] ToggleButton _lStickLeft;
@@ -88,6 +89,7 @@ namespace Ryujinx.Ui.Windows
[GUI] ToggleButton _rStick; [GUI] ToggleButton _rStick;
[GUI] CheckButton _invertRStickX; [GUI] CheckButton _invertRStickX;
[GUI] CheckButton _invertRStickY; [GUI] CheckButton _invertRStickY;
[GUI] CheckButton _rotateR90CW;
[GUI] ToggleButton _rStickUp; [GUI] ToggleButton _rStickUp;
[GUI] ToggleButton _rStickDown; [GUI] ToggleButton _rStickDown;
[GUI] ToggleButton _rStickLeft; [GUI] ToggleButton _rStickLeft;
@@ -490,6 +492,7 @@ namespace Ryujinx.Ui.Windows
_lStick.Label = controllerConfig.LeftJoyconStick.Joystick.ToString(); _lStick.Label = controllerConfig.LeftJoyconStick.Joystick.ToString();
_invertLStickX.Active = controllerConfig.LeftJoyconStick.InvertStickX; _invertLStickX.Active = controllerConfig.LeftJoyconStick.InvertStickX;
_invertLStickY.Active = controllerConfig.LeftJoyconStick.InvertStickY; _invertLStickY.Active = controllerConfig.LeftJoyconStick.InvertStickY;
_rotateL90CW.Active = controllerConfig.LeftJoyconStick.Rotate90CW;
_lStickButton.Label = controllerConfig.LeftJoyconStick.StickButton.ToString(); _lStickButton.Label = controllerConfig.LeftJoyconStick.StickButton.ToString();
_dpadUp.Label = controllerConfig.LeftJoycon.DpadUp.ToString(); _dpadUp.Label = controllerConfig.LeftJoycon.DpadUp.ToString();
_dpadDown.Label = controllerConfig.LeftJoycon.DpadDown.ToString(); _dpadDown.Label = controllerConfig.LeftJoycon.DpadDown.ToString();
@@ -503,6 +506,7 @@ namespace Ryujinx.Ui.Windows
_rStick.Label = controllerConfig.RightJoyconStick.Joystick.ToString(); _rStick.Label = controllerConfig.RightJoyconStick.Joystick.ToString();
_invertRStickX.Active = controllerConfig.RightJoyconStick.InvertStickX; _invertRStickX.Active = controllerConfig.RightJoyconStick.InvertStickX;
_invertRStickY.Active = controllerConfig.RightJoyconStick.InvertStickY; _invertRStickY.Active = controllerConfig.RightJoyconStick.InvertStickY;
_rotateR90CW.Active = controllerConfig.RightJoyconStick.Rotate90CW;
_rStickButton.Label = controllerConfig.RightJoyconStick.StickButton.ToString(); _rStickButton.Label = controllerConfig.RightJoyconStick.StickButton.ToString();
_a.Label = controllerConfig.RightJoycon.ButtonA.ToString(); _a.Label = controllerConfig.RightJoycon.ButtonA.ToString();
_b.Label = controllerConfig.RightJoycon.ButtonB.ToString(); _b.Label = controllerConfig.RightJoycon.ButtonB.ToString();
@@ -718,6 +722,7 @@ namespace Ryujinx.Ui.Windows
Joystick = lStick, Joystick = lStick,
InvertStickY = _invertLStickY.Active, InvertStickY = _invertLStickY.Active,
StickButton = lStickButton, StickButton = lStickButton,
Rotate90CW = _rotateL90CW.Active,
}, },
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId> RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
{ {
@@ -737,6 +742,7 @@ namespace Ryujinx.Ui.Windows
Joystick = rStick, Joystick = rStick,
InvertStickY = _invertRStickY.Active, InvertStickY = _invertRStickY.Active,
StickButton = rStickButton, StickButton = rStickButton,
Rotate90CW = _rotateR90CW.Active,
}, },
Motion = motionConfig, Motion = motionConfig,
Rumble = new RumbleConfigController Rumble = new RumbleConfigController
@@ -1056,6 +1062,7 @@ namespace Ryujinx.Ui.Windows
StickButton = ConfigGamepadInputId.LeftStick, StickButton = ConfigGamepadInputId.LeftStick,
InvertStickX = false, InvertStickX = false,
InvertStickY = false, InvertStickY = false,
Rotate90CW = false,
}, },
RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId> RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
@@ -1077,6 +1084,7 @@ namespace Ryujinx.Ui.Windows
StickButton = ConfigGamepadInputId.RightStick, StickButton = ConfigGamepadInputId.RightStick,
InvertStickX = false, InvertStickX = false,
InvertStickY = false, InvertStickY = false,
Rotate90CW = false,
}, },
Motion = new StandardMotionConfigController Motion = new StandardMotionConfigController

View File

@@ -740,6 +740,19 @@
<property name="top_attach">1</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="_rotateL90CW">
<property name="label" translatable="yes">Rotate 90° Clockwise</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -1697,6 +1710,19 @@
<property name="top_attach">1</property> <property name="top_attach">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="_rotateR90CW">
<property name="label" translatable="yes">Rotate 90° Clockwise</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>