diff --git a/src/ARMeilleure/Optimizations.cs b/src/ARMeilleure/Optimizations.cs index 8fe478e47..3cc8acc8d 100644 --- a/src/ARMeilleure/Optimizations.cs +++ b/src/ARMeilleure/Optimizations.cs @@ -9,6 +9,7 @@ namespace ARMeilleure public static bool AllowLcqInFunctionTable { get; set; } = true; public static bool UseUnmanagedDispatchLoop { get; set; } = true; + public static bool EnableDebugging { get; set; } = false; public static bool UseAdvSimdIfAvailable { get; set; } = true; public static bool UseArm64AesIfAvailable { get; set; } = true; diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index 014b12035..410444c78 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -140,7 +140,33 @@ namespace ARMeilleure.Translation NativeInterface.RegisterThread(context, Memory, this); - if (Optimizations.UseUnmanagedDispatchLoop) + if (Optimizations.EnableDebugging) + { + context.DebugPc = address; + do + { + context.DebugPc = ExecuteSingle(context, context.DebugPc); + + while (context._debugState != (int)DebugState.Running) + { + Interlocked.CompareExchange(ref context._debugState, (int)DebugState.Stopped, (int)DebugState.Stopping); + context._debugHalt.WaitOne(); + if (Interlocked.CompareExchange(ref context._shouldStep, 0, 1) == 1) + { + context.DebugPc = Step(context, context.DebugPc); + + context._stepBarrier.SignalAndWait(); + context._stepBarrier.SignalAndWait(); + } + else + { + Interlocked.CompareExchange(ref context._debugState, (int)DebugState.Running, (int)DebugState.Stopped); + } + } + } + while (context.Running && context.DebugPc != 0); + } + else if (Optimizations.UseUnmanagedDispatchLoop) { Stubs.DispatchLoop(context.NativeContextPtr, address); } @@ -249,7 +275,7 @@ namespace ARMeilleure.Translation Stubs, address, highCq, - _ptc.State != PtcState.Disabled, + _ptc.State != PtcState.Disabled && !Optimizations.EnableDebugging, mode: Aarch32Mode.User); Logger.StartPass(PassName.Decoding); @@ -382,9 +408,8 @@ namespace ARMeilleure.Translation if (block.Exit) { - // Left option here as it may be useful if we need to return to managed rather than tail call in - // future. (eg. for debug) - bool useReturns = false; + // Return to managed rather than tail call. + bool useReturns = Optimizations.EnableDebugging; InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns); }