2018-02-25 20:14:58 -05:00
|
|
|
using ChocolArm64.Events;
|
2018-02-04 18:08:20 -05:00
|
|
|
using System;
|
2018-04-22 00:21:49 -04:00
|
|
|
using System.Collections.Generic;
|
2018-03-13 20:24:17 -04:00
|
|
|
using System.Diagnostics;
|
2018-05-11 19:10:27 -04:00
|
|
|
using System.Runtime.Intrinsics;
|
2018-02-04 18:08:20 -05:00
|
|
|
|
|
|
|
namespace ChocolArm64.State
|
|
|
|
{
|
2018-02-18 14:28:07 -05:00
|
|
|
public class AThreadState
|
2018-02-04 18:08:20 -05:00
|
|
|
{
|
|
|
|
internal const int LRIndex = 30;
|
|
|
|
internal const int ZRIndex = 31;
|
|
|
|
|
2018-02-06 10:15:08 -05:00
|
|
|
internal const int ErgSizeLog2 = 4;
|
|
|
|
internal const int DczSizeLog2 = 4;
|
|
|
|
|
2018-05-26 16:49:21 -04:00
|
|
|
internal AExecutionMode ExecutionMode;
|
|
|
|
|
|
|
|
//AArch32 state.
|
|
|
|
public uint R0, R1, R2, R3,
|
|
|
|
R4, R5, R6, R7,
|
|
|
|
R8, R9, R10, R11,
|
|
|
|
R12, R13, R14, R15;
|
|
|
|
|
|
|
|
public bool Thumb;
|
|
|
|
|
|
|
|
//AArch64 state.
|
2018-02-04 18:08:20 -05:00
|
|
|
public ulong X0, X1, X2, X3, X4, X5, X6, X7,
|
|
|
|
X8, X9, X10, X11, X12, X13, X14, X15,
|
|
|
|
X16, X17, X18, X19, X20, X21, X22, X23,
|
|
|
|
X24, X25, X26, X27, X28, X29, X30, X31;
|
|
|
|
|
2018-05-11 19:10:27 -04:00
|
|
|
public Vector128<float> V0, V1, V2, V3, V4, V5, V6, V7,
|
|
|
|
V8, V9, V10, V11, V12, V13, V14, V15,
|
|
|
|
V16, V17, V18, V19, V20, V21, V22, V23,
|
|
|
|
V24, V25, V26, V27, V28, V29, V30, V31;
|
2018-02-04 18:08:20 -05:00
|
|
|
|
|
|
|
public bool Overflow;
|
|
|
|
public bool Carry;
|
|
|
|
public bool Zero;
|
|
|
|
public bool Negative;
|
|
|
|
|
2018-03-12 00:04:52 -04:00
|
|
|
public bool Running { get; set; }
|
2018-09-18 19:36:43 -04:00
|
|
|
public int Core { get; set; }
|
|
|
|
|
|
|
|
private bool Interrupted;
|
2018-03-12 00:04:52 -04:00
|
|
|
|
2018-02-06 10:15:08 -05:00
|
|
|
public long TpidrEl0 { get; set; }
|
|
|
|
public long Tpidr { get; set; }
|
2018-02-04 18:08:20 -05:00
|
|
|
|
2018-02-06 10:15:08 -05:00
|
|
|
public int Fpcr { get; set; }
|
|
|
|
public int Fpsr { get; set; }
|
2018-02-04 18:08:20 -05:00
|
|
|
|
2018-06-26 00:09:32 -04:00
|
|
|
public int Psr
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return (Negative ? (int)APState.N : 0) |
|
|
|
|
(Zero ? (int)APState.Z : 0) |
|
|
|
|
(Carry ? (int)APState.C : 0) |
|
|
|
|
(Overflow ? (int)APState.V : 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-06 10:15:08 -05:00
|
|
|
public uint CtrEl0 => 0x8444c004;
|
|
|
|
public uint DczidEl0 => 0x00000004;
|
2018-02-04 18:08:20 -05:00
|
|
|
|
2018-03-13 20:24:17 -04:00
|
|
|
public ulong CntfrqEl0 { get; set; }
|
|
|
|
public ulong CntpctEl0
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
double Ticks = TickCounter.ElapsedTicks * HostTickFreq;
|
2018-02-11 22:37:20 -05:00
|
|
|
|
2018-03-13 20:24:17 -04:00
|
|
|
return (ulong)(Ticks * CntfrqEl0);
|
|
|
|
}
|
|
|
|
}
|
2018-02-04 18:08:20 -05:00
|
|
|
|
2018-09-18 19:36:43 -04:00
|
|
|
public event EventHandler<EventArgs> Interrupt;
|
2018-02-25 20:14:58 -05:00
|
|
|
public event EventHandler<AInstExceptionEventArgs> Break;
|
|
|
|
public event EventHandler<AInstExceptionEventArgs> SvcCall;
|
|
|
|
public event EventHandler<AInstUndefinedEventArgs> Undefined;
|
2018-02-10 08:24:16 -05:00
|
|
|
|
2018-04-22 00:21:49 -04:00
|
|
|
private Stack<long> CallStack;
|
|
|
|
|
2018-03-13 20:24:17 -04:00
|
|
|
private static Stopwatch TickCounter;
|
|
|
|
|
|
|
|
private static double HostTickFreq;
|
|
|
|
|
2018-04-22 00:21:49 -04:00
|
|
|
public AThreadState()
|
|
|
|
{
|
|
|
|
CallStack = new Stack<long>();
|
|
|
|
}
|
|
|
|
|
2018-03-13 20:24:17 -04:00
|
|
|
static AThreadState()
|
|
|
|
{
|
|
|
|
HostTickFreq = 1.0 / Stopwatch.Frequency;
|
|
|
|
|
|
|
|
TickCounter = new Stopwatch();
|
|
|
|
|
|
|
|
TickCounter.Start();
|
|
|
|
}
|
|
|
|
|
2018-08-16 19:47:36 -04:00
|
|
|
internal bool Synchronize()
|
|
|
|
{
|
2018-09-18 19:36:43 -04:00
|
|
|
if (Interrupted)
|
|
|
|
{
|
|
|
|
Interrupted = false;
|
|
|
|
|
|
|
|
OnInterrupt();
|
|
|
|
}
|
|
|
|
|
2018-08-16 19:47:36 -04:00
|
|
|
return Running;
|
|
|
|
}
|
|
|
|
|
2018-09-18 19:36:43 -04:00
|
|
|
internal void RequestInterrupt()
|
|
|
|
{
|
|
|
|
Interrupted = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void OnInterrupt()
|
|
|
|
{
|
|
|
|
Interrupt?.Invoke(this, EventArgs.Empty);
|
|
|
|
}
|
|
|
|
|
2018-06-26 00:09:32 -04:00
|
|
|
internal void OnBreak(long Position, int Imm)
|
2018-02-10 08:24:16 -05:00
|
|
|
{
|
2018-06-26 00:09:32 -04:00
|
|
|
Break?.Invoke(this, new AInstExceptionEventArgs(Position, Imm));
|
2018-02-10 08:24:16 -05:00
|
|
|
}
|
2018-02-04 18:08:20 -05:00
|
|
|
|
2018-06-26 00:09:32 -04:00
|
|
|
internal void OnSvcCall(long Position, int Imm)
|
2018-02-04 18:08:20 -05:00
|
|
|
{
|
2018-06-26 00:09:32 -04:00
|
|
|
SvcCall?.Invoke(this, new AInstExceptionEventArgs(Position, Imm));
|
2018-02-04 18:08:20 -05:00
|
|
|
}
|
|
|
|
|
2018-02-11 22:37:20 -05:00
|
|
|
internal void OnUndefined(long Position, int RawOpCode)
|
2018-02-04 18:08:20 -05:00
|
|
|
{
|
2018-02-25 20:14:58 -05:00
|
|
|
Undefined?.Invoke(this, new AInstUndefinedEventArgs(Position, RawOpCode));
|
2018-02-04 18:08:20 -05:00
|
|
|
}
|
2018-04-22 00:21:49 -04:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2018-02-04 18:08:20 -05:00
|
|
|
}
|
|
|
|
}
|