Просмотр исходного кода

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.
Luke Warner 1 год назад
Родитель
Сommit
c0a4d95c5d
2 измененных файлов с 26 добавлено и 0 удалено
  1. 17 0
      src/ARMeilleure/Instructions/InstEmitSystem.cs
  2. 9 0
      src/ARMeilleure/State/NativeContext.cs

+ 17 - 0
src/ARMeilleure/Instructions/InstEmitSystem.cs

@@ -49,6 +49,9 @@ namespace ARMeilleure.Instructions
                 case 0b11_011_1101_0000_011:
                 case 0b11_011_1101_0000_011:
                     EmitGetTpidrroEl0(context);
                     EmitGetTpidrroEl0(context);
                     return;
                     return;
+                case 0b11_011_1101_0000_101:
+                    EmitGetTpidr2El0(context);
+                    return;
                 case 0b11_011_1110_0000_000:
                 case 0b11_011_1110_0000_000:
                     info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0));
                     info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0));
                     break;
                     break;
@@ -84,6 +87,9 @@ namespace ARMeilleure.Instructions
                 case 0b11_011_1101_0000_010:
                 case 0b11_011_1101_0000_010:
                     EmitSetTpidrEl0(context);
                     EmitSetTpidrEl0(context);
                     return;
                     return;
+                case 0b11_011_1101_0000_101:
+                    EmitGetTpidr2El0(context);
+                    return;
 
 
                 default:
                 default:
                     throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
                     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);
             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)
         private static void EmitSetNzcv(ArmEmitterContext context)
         {
         {
             OpCodeSystem op = (OpCodeSystem)context.CurrOp;
             OpCodeSystem op = (OpCodeSystem)context.CurrOp;

+ 9 - 0
src/ARMeilleure/State/NativeContext.cs

@@ -21,6 +21,7 @@ namespace ARMeilleure.State
             public ulong ExclusiveValueLow;
             public ulong ExclusiveValueLow;
             public ulong ExclusiveValueHigh;
             public ulong ExclusiveValueHigh;
             public int Running;
             public int Running;
+            public long Tpidr2El0;
         }
         }
 
 
         private static NativeCtxStorage _dummyStorage = new();
         private static NativeCtxStorage _dummyStorage = new();
@@ -176,6 +177,9 @@ namespace ARMeilleure.State
         public long GetTpidrroEl0() => GetStorage().TpidrroEl0;
         public long GetTpidrroEl0() => GetStorage().TpidrroEl0;
         public void SetTpidrroEl0(long value) => GetStorage().TpidrroEl0 = value;
         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 int GetCounter() => GetStorage().Counter;
         public void SetCounter(int value) => GetStorage().Counter = value;
         public void SetCounter(int value) => GetStorage().Counter = value;
 
 
@@ -232,6 +236,11 @@ namespace ARMeilleure.State
             return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrroEl0);
             return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrroEl0);
         }
         }
 
 
+        public static int GetTpidr2El0Offset()
+        {
+            return StorageOffset(ref _dummyStorage, ref _dummyStorage.Tpidr2El0);
+        }
+
         public static int GetCounterOffset()
         public static int GetCounterOffset()
         {
         {
             return StorageOffset(ref _dummyStorage, ref _dummyStorage.Counter);
             return StorageOffset(ref _dummyStorage, ref _dummyStorage.Counter);