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 bool DisableMemoryChecks = false;
|
||||
|
||||
public static bool GenerateCallStack = true;
|
||||
}
|
|
@ -8,8 +8,6 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
static partial class AInstEmit
|
||||
{
|
||||
private const BindingFlags Binding = BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
|
||||
public static void Brk(AILEmitterCtx Context)
|
||||
{
|
||||
EmitExceptionCall(Context, nameof(AThreadState.OnBreak));
|
||||
|
@ -30,9 +28,7 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
Context.EmitLdc_I4(Op.Id);
|
||||
|
||||
MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
|
||||
|
||||
Context.EmitCall(MthdInfo);
|
||||
Context.EmitPrivateCall(typeof(AThreadState), MthdName);
|
||||
|
||||
//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.
|
||||
|
@ -73,11 +69,7 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitLdc_I8(Op.Position);
|
||||
Context.EmitLdc_I4(Op.RawOpCode);
|
||||
|
||||
string MthdName = nameof(AThreadState.OnUndefined);
|
||||
|
||||
MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
|
||||
|
||||
Context.EmitCall(MthdInfo);
|
||||
Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.OnUndefined));
|
||||
|
||||
if (Context.CurrBlock.Next != null)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,14 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
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.EmitStint(AThreadState.LRIndex);
|
||||
Context.EmitStoreState();
|
||||
|
@ -72,6 +80,14 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
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.EmitStint(AThreadState.LRIndex);
|
||||
Context.EmitStoreState();
|
||||
|
@ -84,6 +100,14 @@ namespace ChocolArm64.Instruction
|
|||
{
|
||||
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.EmitLdintzr(Op.Rn);
|
||||
|
||||
|
@ -105,6 +129,13 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
public static void Ret(AILEmitterCtx Context)
|
||||
{
|
||||
if (AOptimizations.GenerateCallStack)
|
||||
{
|
||||
Context.EmitLdarg(ATranslatedSub.StateArgIdx);
|
||||
|
||||
Context.EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.ExitMethod));
|
||||
}
|
||||
|
||||
Context.EmitStoreState();
|
||||
Context.EmitLdint(AThreadState.LRIndex);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using ChocolArm64.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ChocolArm64.State
|
||||
|
@ -56,10 +57,17 @@ namespace ChocolArm64.State
|
|||
public event EventHandler<AInstExceptionEventArgs> SvcCall;
|
||||
public event EventHandler<AInstUndefinedEventArgs> Undefined;
|
||||
|
||||
private Stack<long> CallStack;
|
||||
|
||||
private static Stopwatch TickCounter;
|
||||
|
||||
private static double HostTickFreq;
|
||||
|
||||
public AThreadState()
|
||||
{
|
||||
CallStack = new Stack<long>();
|
||||
}
|
||||
|
||||
static AThreadState()
|
||||
{
|
||||
HostTickFreq = 1.0 / Stopwatch.Frequency;
|
||||
|
@ -83,5 +91,27 @@ namespace ChocolArm64.State
|
|||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (MthdInfo == null)
|
||||
|
|
Loading…
Reference in a new issue