diff options
| author | riperiperi <rhy3756547@hotmail.com> | 2023-04-11 07:55:04 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-11 08:55:04 +0200 |
| commit | 9ef94c8292beda825fa76e05ad2e561c6d571c95 (patch) | |
| tree | e535eef49837759f9947bac48a8cbf0b91512d9e /ARMeilleure/Instructions/InstEmitSystem32.cs | |
| parent | 915d6d044cbf8c89935f14b8c7e085ad729f0e28 (diff) | |
ARMeilleure: Move TPIDR_EL0 and TPIDRRO_EL0 to NativeContext (#4661)
* 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
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitSystem32.cs')
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitSystem32.cs | 47 |
1 files changed, 35 insertions, 12 deletions
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)); + } } } |
