blob: facb9142f927b632ee452ff180ba86c98d2fa0b1 (
plain) (
tree)
|
|
using ARMeilleure.Memory;
using ARMeilleure.State;
using System;
namespace Ryujinx.Cpu.LightningJit.State
{
public class ExecutionContext : IExecutionContext
{
private const int MinCountForCheck = 4000;
private readonly NativeContext _nativeContext;
internal IntPtr NativeContextPtr => _nativeContext.BasePtr;
private bool _interrupted;
private readonly ICounter _counter;
public ulong Pc => _nativeContext.GetPc();
public ulong CntfrqEl0 => _counter.Frequency;
public ulong CntpctEl0 => _counter.Counter;
public long TpidrEl0
{
get => _nativeContext.GetTpidrEl0();
set => _nativeContext.SetTpidrEl0(value);
}
public long TpidrroEl0
{
get => _nativeContext.GetTpidrroEl0();
set => _nativeContext.SetTpidrroEl0(value);
}
public uint Pstate
{
get => _nativeContext.GetPstate();
set => _nativeContext.SetPstate(value);
}
public uint Fpsr
{
get => _nativeContext.GetFPState((uint)FPSR.Mask);
set => _nativeContext.SetFPState(value, (uint)FPSR.Mask);
}
public uint Fpcr
{
get => _nativeContext.GetFPState((uint)FPCR.Mask);
set => _nativeContext.SetFPState(value, (uint)FPCR.Mask);
}
public bool IsAarch32 { get; set; }
internal ExecutionMode ExecutionMode
{
get
{
if (IsAarch32)
{
return (Pstate & (1u << 5)) != 0
? ExecutionMode.Aarch32Thumb
: ExecutionMode.Aarch32Arm;
}
else
{
return ExecutionMode.Aarch64;
}
}
}
public bool Running
{
get => _nativeContext.GetRunning();
private set => _nativeContext.SetRunning(value);
}
private readonly ExceptionCallbackNoArgs _interruptCallback;
private readonly ExceptionCallback _breakCallback;
private readonly ExceptionCallback _supervisorCallback;
private readonly ExceptionCallback _undefinedCallback;
public ExecutionContext(IJitMemoryAllocator allocator, ICounter counter, ExceptionCallbacks exceptionCallbacks)
{
_nativeContext = new NativeContext(allocator);
_counter = counter;
_interruptCallback = exceptionCallbacks.InterruptCallback;
_breakCallback = exceptionCallbacks.BreakCallback;
_supervisorCallback = exceptionCallbacks.SupervisorCallback;
_undefinedCallback = exceptionCallbacks.UndefinedCallback;
Running = true;
_nativeContext.SetCounter(MinCountForCheck);
}
public ulong GetX(int index) => _nativeContext.GetX(index);
public void SetX(int index, ulong value) => _nativeContext.SetX(index, value);
public V128 GetV(int index) => _nativeContext.GetV(index);
public void SetV(int index, V128 value) => _nativeContext.SetV(index, value);
internal void CheckInterrupt()
{
if (_interrupted)
{
_interrupted = false;
_interruptCallback?.Invoke(this);
}
_nativeContext.SetCounter(MinCountForCheck);
}
public void RequestInterrupt()
{
_interrupted = true;
}
internal void OnBreak(ulong address, int imm)
{
_breakCallback?.Invoke(this, address, imm);
}
internal void OnSupervisorCall(ulong address, int imm)
{
_supervisorCallback?.Invoke(this, address, imm);
}
internal void OnUndefined(ulong address, int opCode)
{
_undefinedCallback?.Invoke(this, address, opCode);
}
public void StopRunning()
{
Running = false;
_nativeContext.SetCounter(0);
}
protected virtual void Dispose(bool disposing)
{
_nativeContext.Dispose();
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}
|