diff --git a/ARMeilleure/Instructions/InstEmitSystem.cs b/ARMeilleure/Instructions/InstEmitSystem.cs index f668b83b6..f84829aa1 100644 --- a/ARMeilleure/Instructions/InstEmitSystem.cs +++ b/ARMeilleure/Instructions/InstEmitSystem.cs @@ -33,8 +33,8 @@ namespace ARMeilleure.Instructions case 0b11_011_0100_0010_000: EmitGetNzcv(context); return; case 0b11_011_0100_0100_000: EmitGetFpcr(context); return; case 0b11_011_0100_0100_001: EmitGetFpsr(context); return; - case 0b11_011_1101_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl0)); break; - case 0b11_011_1101_0000_011: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrroEl0)); break; + case 0b11_011_1101_0000_010: EmitGetTpidrEl0(context); return; + case 0b11_011_1101_0000_011: EmitGetTpidrroEl0(context); return; case 0b11_011_1110_0000_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)); break; case 0b11_011_1110_0000_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntpctEl0)); break; case 0b11_011_1110_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0)); break; @@ -49,19 +49,15 @@ namespace ARMeilleure.Instructions { OpCodeSystem op = (OpCodeSystem)context.CurrOp; - MethodInfo info; - switch (GetPackedId(op)) { case 0b11_011_0100_0010_000: EmitSetNzcv(context); return; case 0b11_011_0100_0100_000: EmitSetFpcr(context); return; case 0b11_011_0100_0100_001: EmitSetFpsr(context); return; - case 0b11_011_1101_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)); break; + case 0b11_011_1101_0000_010: EmitSetTpidrEl0(context); return; default: throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - - context.Call(info, GetIntOrZR(context, op.Rt)); } public static void Nop(ArmEmitterContext context) @@ -165,6 +161,28 @@ namespace ARMeilleure.Instructions SetIntOrZR(context, op.Rt, fpsr); } + private static void EmitGetTpidrEl0(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.GetTpidrEl0Offset()))); + + SetIntOrZR(context, op.Rt, result); + } + + private static void EmitGetTpidrroEl0(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.GetTpidrroEl0Offset()))); + + SetIntOrZR(context, op.Rt, result); + } + private static void EmitSetNzcv(ArmEmitterContext context) { OpCodeSystem op = (OpCodeSystem)context.CurrOp; @@ -215,5 +233,16 @@ namespace ARMeilleure.Instructions context.UpdateArmFpMode(); } + + private static void EmitSetTpidrEl0(ArmEmitterContext context) + { + OpCodeSystem op = (OpCodeSystem)context.CurrOp; + + Operand value = GetIntOrZR(context, op.Rt); + + Operand nativeContext = context.LoadArgument(OperandType.I64, 0); + + context.Store(context.Add(nativeContext, Const((ulong)NativeContext.GetTpidrEl0Offset())), value); + } } } diff --git a/ARMeilleure/Instructions/InstEmitSystem32.cs b/ARMeilleure/Instructions/InstEmitSystem32.cs index 2f6cf19d6..f2732c998 100644 --- a/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -23,8 +23,6 @@ namespace ARMeilleure.Instructions return; } - MethodInfo info; - switch (op.CRn) { case 13: // Process and Thread Info. @@ -36,14 +34,12 @@ namespace ARMeilleure.Instructions switch (op.Opc2) { case 2: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032)); break; + EmitSetTpidrEl0(context); return; default: throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."); } - break; - case 7: switch (op.CRm) // Cache and Memory barrier. { @@ -64,8 +60,6 @@ namespace ARMeilleure.Instructions default: throw new NotImplementedException($"Unknown MRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - - context.Call(info, GetIntA32(context, op.Rt)); } public static void Mrc(ArmEmitterContext context) @@ -79,7 +73,7 @@ namespace ARMeilleure.Instructions return; } - MethodInfo info; + Operand result; switch (op.CRn) { @@ -92,10 +86,10 @@ namespace ARMeilleure.Instructions switch (op.Opc2) { case 2: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl032)); break; + result = EmitGetTpidrEl0(context); break; case 3: - info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidr32)); break; + result = EmitGetTpidrroEl0(context); break; default: throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X} at 0x{op.Address:X} (0x{op.RawOpCode:X})."); @@ -110,13 +104,13 @@ namespace ARMeilleure.Instructions if (op.Rt == RegisterAlias.Aarch32Pc) { // Special behavior: copy NZCV flags into APSR. - EmitSetNzcv(context, context.Call(info)); + EmitSetNzcv(context, result); return; } else { - SetIntA32(context, op.Rt, context.Call(info)); + SetIntA32(context, op.Rt, result); } } @@ -324,5 +318,34 @@ namespace ARMeilleure.Instructions context.UpdateArmFpMode(); } + + private static Operand EmitGetTpidrEl0(ArmEmitterContext context) + { + OpCode32System op = (OpCode32System)context.CurrOp; + + Operand nativeContext = context.LoadArgument(OperandType.I64, 0); + + return context.Load(OperandType.I64, context.Add(nativeContext, Const((ulong)NativeContext.GetTpidrEl0Offset()))); + } + + private static Operand EmitGetTpidrroEl0(ArmEmitterContext context) + { + OpCode32System op = (OpCode32System)context.CurrOp; + + Operand nativeContext = context.LoadArgument(OperandType.I64, 0); + + return context.Load(OperandType.I64, context.Add(nativeContext, Const((ulong)NativeContext.GetTpidrroEl0Offset()))); + } + + private static void EmitSetTpidrEl0(ArmEmitterContext context) + { + OpCode32System op = (OpCode32System)context.CurrOp; + + Operand value = GetIntA32(context, op.Rt); + + Operand nativeContext = context.LoadArgument(OperandType.I64, 0); + + context.Store(context.Add(nativeContext, Const((ulong)NativeContext.GetTpidrEl0Offset())), context.ZeroExtend32(OperandType.I64, value)); + } } } diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs index 57964cc8d..2c35387a6 100644 --- a/ARMeilleure/Instructions/NativeInterface.cs +++ b/ARMeilleure/Instructions/NativeInterface.cs @@ -72,26 +72,6 @@ namespace ARMeilleure.Instructions return (ulong)GetContext().DczidEl0; } - public static ulong GetTpidrEl0() - { - return (ulong)GetContext().TpidrEl0; - } - - public static uint GetTpidrEl032() - { - return (uint)GetContext().TpidrEl0; - } - - public static ulong GetTpidrroEl0() - { - return (ulong)GetContext().TpidrroEl0; - } - - public static uint GetTpidr32() - { - return (uint)GetContext().TpidrroEl0; - } - public static ulong GetCntfrqEl0() { return GetContext().CntfrqEl0; @@ -106,16 +86,6 @@ namespace ARMeilleure.Instructions { return GetContext().CntvctEl0; } - - public static void SetTpidrEl0(ulong value) - { - GetContext().TpidrEl0 = (long)value; - } - - public static void SetTpidrEl032(uint value) - { - GetContext().TpidrEl0 = (long)value; - } #endregion #region "Read" diff --git a/ARMeilleure/State/ExecutionContext.cs b/ARMeilleure/State/ExecutionContext.cs index 5d18e6ed8..859fb3a5d 100644 --- a/ARMeilleure/State/ExecutionContext.cs +++ b/ARMeilleure/State/ExecutionContext.cs @@ -27,8 +27,17 @@ namespace ARMeilleure.State // Since EL2 isn't implemented, CNTVOFF_EL2 = 0 public ulong CntvctEl0 => CntpctEl0; - public long TpidrEl0 { get; set; } - public long TpidrroEl0 { get; set; } + public long TpidrEl0 + { + get => _nativeContext.GetTpidrEl0(); + set => _nativeContext.SetTpidrEl0(value); + } + + public long TpidrroEl0 + { + get => _nativeContext.GetTpidrroEl0(); + set => _nativeContext.SetTpidrroEl0(value); + } public uint Pstate { diff --git a/ARMeilleure/State/NativeContext.cs b/ARMeilleure/State/NativeContext.cs index 89e875d12..3189bdd8a 100644 --- a/ARMeilleure/State/NativeContext.cs +++ b/ARMeilleure/State/NativeContext.cs @@ -13,6 +13,8 @@ namespace ARMeilleure.State public fixed ulong V[RegisterConsts.VecRegsCount * 2]; public fixed uint Flags[RegisterConsts.FlagsCount]; public fixed uint FpFlags[RegisterConsts.FpFlagsCount]; + public long TpidrEl0; + public long TpidrroEl0; public int Counter; public ulong DispatchAddress; public ulong ExclusiveAddress; @@ -168,6 +170,12 @@ namespace ARMeilleure.State } } + public long GetTpidrEl0() => GetStorage().TpidrEl0; + public void SetTpidrEl0(long value) => GetStorage().TpidrEl0 = value; + + public long GetTpidrroEl0() => GetStorage().TpidrroEl0; + public void SetTpidrroEl0(long value) => GetStorage().TpidrroEl0 = value; + public int GetCounter() => GetStorage().Counter; public void SetCounter(int value) => GetStorage().Counter = value; @@ -214,6 +222,16 @@ namespace ARMeilleure.State } } + public static int GetTpidrEl0Offset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrEl0); + } + + public static int GetTpidrroEl0Offset() + { + return StorageOffset(ref _dummyStorage, ref _dummyStorage.TpidrroEl0); + } + public static int GetCounterOffset() { return StorageOffset(ref _dummyStorage, ref _dummyStorage.Counter); diff --git a/ARMeilleure/Translation/Delegates.cs b/ARMeilleure/Translation/Delegates.cs index 9d3fdc172..55f1e5145 100644 --- a/ARMeilleure/Translation/Delegates.cs +++ b/ARMeilleure/Translation/Delegates.cs @@ -105,17 +105,11 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrroEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidr32))); // A32 only. - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl032))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadByte))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt16))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SupervisorCall))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ThrowInvalidMemoryAccess))); diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index 5970c4ff9..ea4e715b5 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -30,7 +30,7 @@ namespace ARMeilleure.Translation.PTC private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0"; - private const uint InternalVersion = 4626; //! To be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 4661; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1";