Stub a few services, add support for generating call stacks on the CPU
This commit is contained in:
parent
9c43b14421
commit
28f7c6decf
5 changed files with 80 additions and 10 deletions
|
@ -1,4 +1,6 @@
|
||||||
public static class AOptimizations
|
public static class AOptimizations
|
||||||
{
|
{
|
||||||
public static bool DisableMemoryChecks = false;
|
public static bool DisableMemoryChecks = false;
|
||||||
|
|
||||||
|
public static bool GenerateCallStack = true;
|
||||||
}
|
}
|
|
@ -8,8 +8,6 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
static partial class AInstEmit
|
static partial class AInstEmit
|
||||||
{
|
{
|
||||||
private const BindingFlags Binding = BindingFlags.NonPublic | BindingFlags.Instance;
|
|
||||||
|
|
||||||
public static void Brk(AILEmitterCtx Context)
|
public static void Brk(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
EmitExceptionCall(Context, nameof(AThreadState.OnBreak));
|
EmitExceptionCall(Context, nameof(AThreadState.OnBreak));
|
||||||
|
@ -30,9 +28,7 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
Context.EmitLdc_I4(Op.Id);
|
Context.EmitLdc_I4(Op.Id);
|
||||||
|
|
||||||
MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
|
Context.EmitPrivateCall(typeof(AThreadState), MthdName);
|
||||||
|
|
||||||
Context.EmitCall(MthdInfo);
|
|
||||||
|
|
||||||
//Check if the thread should still be running, if it isn't then we return 0
|
//Check if the thread should still be running, if it isn't then we return 0
|
||||||
//to force a return to the dispatcher and then exit the thread.
|
//to force a return to the dispatcher and then exit the thread.
|
||||||
|
@ -73,11 +69,7 @@ namespace ChocolArm64.Instruction
|
||||||
Context.EmitLdc_I8(Op.Position);
|
Context.EmitLdc_I8(Op.Position);
|
||||||
Context.EmitLdc_I4(Op.RawOpCode);
|
Context.EmitLdc_I4(Op.RawOpCode);
|
||||||
|
|
||||||
string MthdName = nameof(AThreadState.OnUndefined);
|
Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.OnUndefined));
|
||||||
|
|
||||||
MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
|
|
||||||
|
|
||||||
Context.EmitCall(MthdInfo);
|
|
||||||
|
|
||||||
if (Context.CurrBlock.Next != null)
|
if (Context.CurrBlock.Next != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,14 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
AOpCodeBImmAl Op = (AOpCodeBImmAl)Context.CurrOp;
|
AOpCodeBImmAl Op = (AOpCodeBImmAl)Context.CurrOp;
|
||||||
|
|
||||||
|
if (AOptimizations.GenerateCallStack)
|
||||||
|
{
|
||||||
|
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||||
|
Context.EmitLdc_I8(Op.Imm);
|
||||||
|
|
||||||
|
Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.EnterMethod));
|
||||||
|
}
|
||||||
|
|
||||||
Context.EmitLdc_I(Op.Position + 4);
|
Context.EmitLdc_I(Op.Position + 4);
|
||||||
Context.EmitStint(AThreadState.LRIndex);
|
Context.EmitStint(AThreadState.LRIndex);
|
||||||
Context.EmitStoreState();
|
Context.EmitStoreState();
|
||||||
|
@ -72,6 +80,14 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp;
|
AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp;
|
||||||
|
|
||||||
|
if (AOptimizations.GenerateCallStack)
|
||||||
|
{
|
||||||
|
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||||
|
Context.EmitLdintzr(Op.Rn);
|
||||||
|
|
||||||
|
Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.EnterMethod));
|
||||||
|
}
|
||||||
|
|
||||||
Context.EmitLdc_I(Op.Position + 4);
|
Context.EmitLdc_I(Op.Position + 4);
|
||||||
Context.EmitStint(AThreadState.LRIndex);
|
Context.EmitStint(AThreadState.LRIndex);
|
||||||
Context.EmitStoreState();
|
Context.EmitStoreState();
|
||||||
|
@ -84,6 +100,14 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp;
|
AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp;
|
||||||
|
|
||||||
|
if (AOptimizations.GenerateCallStack)
|
||||||
|
{
|
||||||
|
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||||
|
Context.EmitLdintzr(Op.Rn);
|
||||||
|
|
||||||
|
Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.JumpMethod));
|
||||||
|
}
|
||||||
|
|
||||||
Context.EmitStoreState();
|
Context.EmitStoreState();
|
||||||
Context.EmitLdintzr(Op.Rn);
|
Context.EmitLdintzr(Op.Rn);
|
||||||
|
|
||||||
|
@ -105,6 +129,13 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
public static void Ret(AILEmitterCtx Context)
|
public static void Ret(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
|
if (AOptimizations.GenerateCallStack)
|
||||||
|
{
|
||||||
|
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||||
|
|
||||||
|
Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.ExitMethod));
|
||||||
|
}
|
||||||
|
|
||||||
Context.EmitStoreState();
|
Context.EmitStoreState();
|
||||||
Context.EmitLdint(AThreadState.LRIndex);
|
Context.EmitLdint(AThreadState.LRIndex);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using ChocolArm64.Events;
|
using ChocolArm64.Events;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace ChocolArm64.State
|
namespace ChocolArm64.State
|
||||||
|
@ -56,10 +57,17 @@ namespace ChocolArm64.State
|
||||||
public event EventHandler<AInstExceptionEventArgs> SvcCall;
|
public event EventHandler<AInstExceptionEventArgs> SvcCall;
|
||||||
public event EventHandler<AInstUndefinedEventArgs> Undefined;
|
public event EventHandler<AInstUndefinedEventArgs> Undefined;
|
||||||
|
|
||||||
|
private Stack<long> CallStack;
|
||||||
|
|
||||||
private static Stopwatch TickCounter;
|
private static Stopwatch TickCounter;
|
||||||
|
|
||||||
private static double HostTickFreq;
|
private static double HostTickFreq;
|
||||||
|
|
||||||
|
public AThreadState()
|
||||||
|
{
|
||||||
|
CallStack = new Stack<long>();
|
||||||
|
}
|
||||||
|
|
||||||
static AThreadState()
|
static AThreadState()
|
||||||
{
|
{
|
||||||
HostTickFreq = 1.0 / Stopwatch.Frequency;
|
HostTickFreq = 1.0 / Stopwatch.Frequency;
|
||||||
|
@ -83,5 +91,27 @@ namespace ChocolArm64.State
|
||||||
{
|
{
|
||||||
Undefined?.Invoke(this, new AInstUndefinedEventArgs(Position, RawOpCode));
|
Undefined?.Invoke(this, new AInstUndefinedEventArgs(Position, RawOpCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void EnterMethod(long Position)
|
||||||
|
{
|
||||||
|
CallStack.Push(Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ExitMethod()
|
||||||
|
{
|
||||||
|
CallStack.TryPop(out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void JumpMethod(long Position)
|
||||||
|
{
|
||||||
|
CallStack.TryPop(out _);
|
||||||
|
|
||||||
|
CallStack.Push(Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long[] GetCallStack()
|
||||||
|
{
|
||||||
|
return CallStack.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -461,6 +461,21 @@ namespace ChocolArm64.Translation
|
||||||
EmitCall(ObjType.GetMethod(MthdName));
|
EmitCall(ObjType.GetMethod(MthdName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EmitPrivateCall(Type ObjType, string MthdName)
|
||||||
|
{
|
||||||
|
if (ObjType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(ObjType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MthdName == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(MthdName));
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitCall(ObjType.GetMethod(MthdName, BindingFlags.Instance | BindingFlags.NonPublic));
|
||||||
|
}
|
||||||
|
|
||||||
public void EmitCall(MethodInfo MthdInfo)
|
public void EmitCall(MethodInfo MthdInfo)
|
||||||
{
|
{
|
||||||
if (MthdInfo == null)
|
if (MthdInfo == null)
|
||||||
|
|
Loading…
Reference in a new issue