From c0a4d95c5d984df4a862a62d21f5090fb88a32de Mon Sep 17 00:00:00 2001 From: Luke Warner <65521430+LukeWarnut@users.noreply.github.com> Date: Tue, 19 Nov 2024 14:02:24 -0500 Subject: [PATCH] ARMeilleure: Implement TPIDR2_EL0 (#280) This is an implementation of the TPIDR2_EL0 register. There may be more potential use-cases for this register not included in this PR, but this implements the use-case seen in SuperTuxKart. --- src/ARMeilleure/Instructions/InstEmitSystem.cs | 17 +++++++++++++++++ src/ARMeilleure/State/NativeContext.cs | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/src/ARMeilleure/Instructions/InstEmitSystem.cs b/src/ARMeilleure/Instructions/InstEmitSystem.cs index 8c430fc23..fbf3b4a70 100644 --- a/src/ARMeilleure/Instructions/InstEmitSystem.cs +++ b/src/ARMeilleure/Instructions/InstEmitSystem.cs @@ -49,6 +49,9 @@ namespace ARMeilleure.Instructions case 0b11_011_1101_0000_011: EmitGetTpidrroEl0(context); return; + case 0b11_011_1101_0000_101: + EmitGetTpidr2El0(context); + return; case 0b11_011_1110_0000_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)); break; @@ -84,6 +87,9 @@ namespace ARMeilleure.Instructions case 0b11_011_1101_0000_010: EmitSetTpidrEl0(context); return; + case 0b11_011_1101_0000_101: + EmitGetTpidr2El0(context); + return; default: throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); @@ -213,6 +219,17 @@ namespace ARMeilleure.Instructions SetIntOrZR(context, op.Rt, result); } + private static void EmitGetTpidr2El0(ArmEmitterContext context) + { + OpCodeSystem op = (OpCodeSystem)context.CurrOp; + + Operand nativeContext = context.LoadArgument(OperandType.I64, 0); + + Operand result = context.Load(OperandType.I64, context.Add(nativeContext, Const((ulong)NativeContext.GetTpidr2El0Offset()))); + + SetIntOrZR(context, op.Rt, result); + } + private static void EmitSetNzcv(ArmEmitterContext context) { OpCodeSystem op = (OpCodeSystem)context.CurrOp; diff --git a/src/ARMeilleure/State/NativeContext.cs b/src/ARMeilleure/State/NativeContext.cs index 628efde41..140b6f7a7 100644 --- a/src/ARMeilleure/State/NativeContext.cs +++ b/src/ARMeilleure/State/NativeContext.cs @@ -21,6 +21,7 @@ namespace ARMeilleure.State public ulong ExclusiveValueLow; public ulong ExclusiveValueHigh; public int Running; + public long Tpidr2El0; } private static NativeCtxStorage _dummyStorage = new(); @@ -176,6 +177,9 @@ namespace ARMeilleure.State public long GetTpidrroEl0() => GetStorage().TpidrroEl0; public void SetTpidrroEl0(long value) => GetStorage().TpidrroEl0 = value; + public long GetTpidr2El0() => GetStorage().Tpidr2El0; + public void SetTpidr2El0(long value) => GetStorage().Tpidr2El0 = value; + public int GetCounter() => GetStorage().Counter; public void SetCounter(int value) => GetStorage().Counter = value; @@ -232,6 +236,11 @@ namespace ARMeilleure.State return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrroEl0); } + public static int GetTpidr2El0Offset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.Tpidr2El0); + } + public static int GetCounterOffset() { return StorageOffset(ref _dummyStorage, ref _dummyStorage.Counter);