aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2023-04-11 07:55:04 +0100
committerGitHub <noreply@github.com>2023-04-11 08:55:04 +0200
commit9ef94c8292beda825fa76e05ad2e561c6d571c95 (patch)
treee535eef49837759f9947bac48a8cbf0b91512d9e
parent915d6d044cbf8c89935f14b8c7e085ad729f0e28 (diff)
ARMeilleure: Move TPIDR_EL0 and TPIDRRO_EL0 to NativeContext (#4661)1.1.705
* ARMeilleure: Move TPIDR_EL0 and TPIDRRO_EL0 to NativeContext Some games access these system registers several tens of thousands of times in a second from many different threads. While this isn't really crippling, it is a lot of wasted time spent in a reverse pinvoke transition. Example games are Pokemon Scarlet/Violet and BOTW. These games have a lot of different potential bottlenecks so it's unlikely you will see a consistent improvement, but it definitely disappears from the cpu profile. * Remove unreachable code. * Add ulong conversion for offsets * Nit
-rw-r--r--ARMeilleure/Instructions/InstEmitSystem.cs43
-rw-r--r--ARMeilleure/Instructions/InstEmitSystem32.cs47
-rw-r--r--ARMeilleure/Instructions/NativeInterface.cs30
-rw-r--r--ARMeilleure/State/ExecutionContext.cs13
-rw-r--r--ARMeilleure/State/NativeContext.cs18
-rw-r--r--ARMeilleure/Translation/Delegates.cs6
-rw-r--r--ARMeilleure/Translation/PTC/Ptc.cs2
7 files changed, 101 insertions, 58 deletions
diff --git a/ARMeilleure/Instructions/InstEmitSystem.cs b/ARMeilleure/Instructions/InstEmitSystem.cs
index f668b83b..f84829aa 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 2f6cf19d..f2732c99 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 57964cc8..2c35387a 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 5d18e6ed..859fb3a5 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 89e875d1..3189bdd8 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 9d3fdc17..55f1e514 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 5970c4ff..ea4e715b 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";