From cffa8905ab9c5e006d21b658188b110941d00c43 Mon Sep 17 00:00:00 2001 From: merry Date: Tue, 8 Feb 2022 19:00:47 +0000 Subject: [PATCH] ARMeilleure: Add debuggable CPU loop --- ARMeilleure/Optimizations.cs | 1 + ARMeilleure/Translation/ArmEmitterContext.cs | 2 +- ARMeilleure/Translation/Translator.cs | 33 +++++++++++++++++--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/ARMeilleure/Optimizations.cs b/ARMeilleure/Optimizations.cs index 986b0c9ec..73c150dc8 100644 --- a/ARMeilleure/Optimizations.cs +++ b/ARMeilleure/Optimizations.cs @@ -8,6 +8,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 UseSseIfAvailable { get; set; } = true; public static bool UseSse2IfAvailable { get; set; } = true; diff --git a/ARMeilleure/Translation/ArmEmitterContext.cs b/ARMeilleure/Translation/ArmEmitterContext.cs index 33355daec..e0ede2054 100644 --- a/ARMeilleure/Translation/ArmEmitterContext.cs +++ b/ARMeilleure/Translation/ArmEmitterContext.cs @@ -68,7 +68,7 @@ namespace ARMeilleure.Translation bool highCq, Aarch32Mode mode) { - HasPtc = Ptc.State != PtcState.Disabled; + HasPtc = Ptc.State != PtcState.Disabled && !Optimizations.EnableDebugging; Memory = memory; CountTable = countTable; FunctionTable = funcTable; diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 389adf292..2ddebefa2 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -169,7 +169,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); } @@ -368,9 +394,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); }