aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/State
diff options
context:
space:
mode:
authoremmauss <emmausssss@gmail.com>2018-02-20 22:09:23 +0200
committergdkchan <gab.dark.100@gmail.com>2018-02-20 17:09:23 -0300
commit62b827f474f0aa2152dd339fcc7cf31084e16a0b (patch)
tree0e5c55b341aee4db0ccb841a084f253ec5e05657 /ChocolArm64/State
parentcb665bb715834526d73c9469d16114b287faaecd (diff)
Split main project into core,graphics and chocolarm4 subproject (#29)
Diffstat (limited to 'ChocolArm64/State')
-rw-r--r--ChocolArm64/State/AInstExceptEventArgs.cs14
-rw-r--r--ChocolArm64/State/AInstUndEventArgs.cs16
-rw-r--r--ChocolArm64/State/APState.cs23
-rw-r--r--ChocolArm64/State/ARegister.cs142
-rw-r--r--ChocolArm64/State/ARegisterSize.cs10
-rw-r--r--ChocolArm64/State/ARegisterType.cs9
-rw-r--r--ChocolArm64/State/AThreadState.cs64
-rw-r--r--ChocolArm64/State/AVec.cs243
8 files changed, 521 insertions, 0 deletions
diff --git a/ChocolArm64/State/AInstExceptEventArgs.cs b/ChocolArm64/State/AInstExceptEventArgs.cs
new file mode 100644
index 00000000..f2ee039b
--- /dev/null
+++ b/ChocolArm64/State/AInstExceptEventArgs.cs
@@ -0,0 +1,14 @@
+using System;
+
+namespace ChocolArm64.State
+{
+ public class AInstExceptEventArgs : EventArgs
+ {
+ public int Id { get; private set; }
+
+ public AInstExceptEventArgs(int Id)
+ {
+ this.Id = Id;
+ }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/AInstUndEventArgs.cs b/ChocolArm64/State/AInstUndEventArgs.cs
new file mode 100644
index 00000000..53de65a3
--- /dev/null
+++ b/ChocolArm64/State/AInstUndEventArgs.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace ChocolArm64.State
+{
+ public class AInstUndEventArgs : EventArgs
+ {
+ public long Position { get; private set; }
+ public int RawOpCode { get; private set; }
+
+ public AInstUndEventArgs(long Position, int RawOpCode)
+ {
+ this.Position = Position;
+ this.RawOpCode = RawOpCode;
+ }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/APState.cs b/ChocolArm64/State/APState.cs
new file mode 100644
index 00000000..f55431a6
--- /dev/null
+++ b/ChocolArm64/State/APState.cs
@@ -0,0 +1,23 @@
+using System;
+
+namespace ChocolArm64.State
+{
+ [Flags]
+ public enum APState
+ {
+ VBit = 28,
+ CBit = 29,
+ ZBit = 30,
+ NBit = 31,
+
+ V = 1 << VBit,
+ C = 1 << CBit,
+ Z = 1 << ZBit,
+ N = 1 << NBit,
+
+ NZ = N | Z,
+ CV = C | V,
+
+ NZCV = NZ | CV
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/ARegister.cs b/ChocolArm64/State/ARegister.cs
new file mode 100644
index 00000000..5861db8c
--- /dev/null
+++ b/ChocolArm64/State/ARegister.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Reflection;
+
+namespace ChocolArm64.State
+{
+ struct ARegister
+ {
+ public int Index;
+
+ public ARegisterType Type;
+
+ public ARegister(int Index, ARegisterType Type)
+ {
+ this.Index = Index;
+ this.Type = Type;
+ }
+
+ public override int GetHashCode()
+ {
+ return (ushort)Index | ((ushort)Type << 16);
+ }
+
+ public override bool Equals(object Obj)
+ {
+ return Obj is ARegister Reg &&
+ Reg.Index == Index &&
+ Reg.Type == Type;
+ }
+
+ public FieldInfo GetField()
+ {
+ switch (Type)
+ {
+ case ARegisterType.Flag: return GetFieldFlag();
+ case ARegisterType.Int: return GetFieldInt();
+ case ARegisterType.Vector: return GetFieldVector();
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ private FieldInfo GetFieldFlag()
+ {
+ switch ((APState)Index)
+ {
+ case APState.VBit: return GetField(nameof(AThreadState.Overflow));
+ case APState.CBit: return GetField(nameof(AThreadState.Carry));
+ case APState.ZBit: return GetField(nameof(AThreadState.Zero));
+ case APState.NBit: return GetField(nameof(AThreadState.Negative));
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ private FieldInfo GetFieldInt()
+ {
+ switch (Index)
+ {
+ case 0: return GetField(nameof(AThreadState.X0));
+ case 1: return GetField(nameof(AThreadState.X1));
+ case 2: return GetField(nameof(AThreadState.X2));
+ case 3: return GetField(nameof(AThreadState.X3));
+ case 4: return GetField(nameof(AThreadState.X4));
+ case 5: return GetField(nameof(AThreadState.X5));
+ case 6: return GetField(nameof(AThreadState.X6));
+ case 7: return GetField(nameof(AThreadState.X7));
+ case 8: return GetField(nameof(AThreadState.X8));
+ case 9: return GetField(nameof(AThreadState.X9));
+ case 10: return GetField(nameof(AThreadState.X10));
+ case 11: return GetField(nameof(AThreadState.X11));
+ case 12: return GetField(nameof(AThreadState.X12));
+ case 13: return GetField(nameof(AThreadState.X13));
+ case 14: return GetField(nameof(AThreadState.X14));
+ case 15: return GetField(nameof(AThreadState.X15));
+ case 16: return GetField(nameof(AThreadState.X16));
+ case 17: return GetField(nameof(AThreadState.X17));
+ case 18: return GetField(nameof(AThreadState.X18));
+ case 19: return GetField(nameof(AThreadState.X19));
+ case 20: return GetField(nameof(AThreadState.X20));
+ case 21: return GetField(nameof(AThreadState.X21));
+ case 22: return GetField(nameof(AThreadState.X22));
+ case 23: return GetField(nameof(AThreadState.X23));
+ case 24: return GetField(nameof(AThreadState.X24));
+ case 25: return GetField(nameof(AThreadState.X25));
+ case 26: return GetField(nameof(AThreadState.X26));
+ case 27: return GetField(nameof(AThreadState.X27));
+ case 28: return GetField(nameof(AThreadState.X28));
+ case 29: return GetField(nameof(AThreadState.X29));
+ case 30: return GetField(nameof(AThreadState.X30));
+ case 31: return GetField(nameof(AThreadState.X31));
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ private FieldInfo GetFieldVector()
+ {
+ switch (Index)
+ {
+ case 0: return GetField(nameof(AThreadState.V0));
+ case 1: return GetField(nameof(AThreadState.V1));
+ case 2: return GetField(nameof(AThreadState.V2));
+ case 3: return GetField(nameof(AThreadState.V3));
+ case 4: return GetField(nameof(AThreadState.V4));
+ case 5: return GetField(nameof(AThreadState.V5));
+ case 6: return GetField(nameof(AThreadState.V6));
+ case 7: return GetField(nameof(AThreadState.V7));
+ case 8: return GetField(nameof(AThreadState.V8));
+ case 9: return GetField(nameof(AThreadState.V9));
+ case 10: return GetField(nameof(AThreadState.V10));
+ case 11: return GetField(nameof(AThreadState.V11));
+ case 12: return GetField(nameof(AThreadState.V12));
+ case 13: return GetField(nameof(AThreadState.V13));
+ case 14: return GetField(nameof(AThreadState.V14));
+ case 15: return GetField(nameof(AThreadState.V15));
+ case 16: return GetField(nameof(AThreadState.V16));
+ case 17: return GetField(nameof(AThreadState.V17));
+ case 18: return GetField(nameof(AThreadState.V18));
+ case 19: return GetField(nameof(AThreadState.V19));
+ case 20: return GetField(nameof(AThreadState.V20));
+ case 21: return GetField(nameof(AThreadState.V21));
+ case 22: return GetField(nameof(AThreadState.V22));
+ case 23: return GetField(nameof(AThreadState.V23));
+ case 24: return GetField(nameof(AThreadState.V24));
+ case 25: return GetField(nameof(AThreadState.V25));
+ case 26: return GetField(nameof(AThreadState.V26));
+ case 27: return GetField(nameof(AThreadState.V27));
+ case 28: return GetField(nameof(AThreadState.V28));
+ case 29: return GetField(nameof(AThreadState.V29));
+ case 30: return GetField(nameof(AThreadState.V30));
+ case 31: return GetField(nameof(AThreadState.V31));
+ }
+
+ throw new InvalidOperationException();
+ }
+
+ private FieldInfo GetField(string Name)
+ {
+ return typeof(AThreadState).GetField(Name);
+ }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/ARegisterSize.cs b/ChocolArm64/State/ARegisterSize.cs
new file mode 100644
index 00000000..144f36b9
--- /dev/null
+++ b/ChocolArm64/State/ARegisterSize.cs
@@ -0,0 +1,10 @@
+namespace ChocolArm64.State
+{
+ enum ARegisterSize
+ {
+ Int32,
+ Int64,
+ SIMD64,
+ SIMD128
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/ARegisterType.cs b/ChocolArm64/State/ARegisterType.cs
new file mode 100644
index 00000000..f9776bb7
--- /dev/null
+++ b/ChocolArm64/State/ARegisterType.cs
@@ -0,0 +1,9 @@
+namespace ChocolArm64.State
+{
+ enum ARegisterType
+ {
+ Flag,
+ Int,
+ Vector
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/AThreadState.cs b/ChocolArm64/State/AThreadState.cs
new file mode 100644
index 00000000..cdab4034
--- /dev/null
+++ b/ChocolArm64/State/AThreadState.cs
@@ -0,0 +1,64 @@
+using System;
+
+namespace ChocolArm64.State
+{
+ public class AThreadState
+ {
+ internal const int LRIndex = 30;
+ internal const int ZRIndex = 31;
+
+ internal const int ErgSizeLog2 = 4;
+ internal const int DczSizeLog2 = 4;
+
+ 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;
+
+ public AVec 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;
+
+ public bool Overflow;
+ public bool Carry;
+ public bool Zero;
+ public bool Negative;
+
+ public int ProcessId;
+ public int ThreadId;
+
+ public long TpidrEl0 { get; set; }
+ public long Tpidr { get; set; }
+
+ public int Fpcr { get; set; }
+ public int Fpsr { get; set; }
+
+ public uint CtrEl0 => 0x8444c004;
+ public uint DczidEl0 => 0x00000004;
+
+ private const long TicksPerS = 19_200_000;
+ private const long TicksPerMS = TicksPerS / 1_000;
+
+ public long CntpctEl0 => Environment.TickCount * TicksPerMS;
+
+ public event EventHandler<AInstExceptEventArgs> Break;
+ public event EventHandler<AInstExceptEventArgs> SvcCall;
+ public event EventHandler<AInstUndEventArgs> Undefined;
+
+ internal void OnBreak(int Imm)
+ {
+ Break?.Invoke(this, new AInstExceptEventArgs(Imm));
+ }
+
+ internal void OnSvcCall(int Imm)
+ {
+ SvcCall?.Invoke(this, new AInstExceptEventArgs(Imm));
+ }
+
+ internal void OnUndefined(long Position, int RawOpCode)
+ {
+ Undefined?.Invoke(this, new AInstUndEventArgs(Position, RawOpCode));
+ }
+ }
+} \ No newline at end of file
diff --git a/ChocolArm64/State/AVec.cs b/ChocolArm64/State/AVec.cs
new file mode 100644
index 00000000..f7eb2e22
--- /dev/null
+++ b/ChocolArm64/State/AVec.cs
@@ -0,0 +1,243 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace ChocolArm64.State
+{
+ [StructLayout(LayoutKind.Explicit, Size = 16)]
+ public struct AVec
+ {
+ [FieldOffset(0x0)] public byte B0;
+ [FieldOffset(0x1)] public byte B1;
+ [FieldOffset(0x2)] public byte B2;
+ [FieldOffset(0x3)] public byte B3;
+ [FieldOffset(0x4)] public byte B4;
+ [FieldOffset(0x5)] public byte B5;
+ [FieldOffset(0x6)] public byte B6;
+ [FieldOffset(0x7)] public byte B7;
+ [FieldOffset(0x8)] public byte B8;
+ [FieldOffset(0x9)] public byte B9;
+ [FieldOffset(0xa)] public byte B10;
+ [FieldOffset(0xb)] public byte B11;
+ [FieldOffset(0xc)] public byte B12;
+ [FieldOffset(0xd)] public byte B13;
+ [FieldOffset(0xe)] public byte B14;
+ [FieldOffset(0xf)] public byte B15;
+
+ [FieldOffset(0x0)] public ushort H0;
+ [FieldOffset(0x2)] public ushort H1;
+ [FieldOffset(0x4)] public ushort H2;
+ [FieldOffset(0x6)] public ushort H3;
+ [FieldOffset(0x8)] public ushort H4;
+ [FieldOffset(0xa)] public ushort H5;
+ [FieldOffset(0xc)] public ushort H6;
+ [FieldOffset(0xe)] public ushort H7;
+
+ [FieldOffset(0x0)] public uint W0;
+ [FieldOffset(0x4)] public uint W1;
+ [FieldOffset(0x8)] public uint W2;
+ [FieldOffset(0xc)] public uint W3;
+
+ [FieldOffset(0x0)] public float S0;
+ [FieldOffset(0x4)] public float S1;
+ [FieldOffset(0x8)] public float S2;
+ [FieldOffset(0xc)] public float S3;
+
+ [FieldOffset(0x0)] public ulong X0;
+ [FieldOffset(0x8)] public ulong X1;
+
+ [FieldOffset(0x0)] public double D0;
+ [FieldOffset(0x8)] public double D1;
+
+ public byte ExtractByte(int Index)
+ {
+ switch (Index)
+ {
+ case 0: return B0;
+ case 1: return B1;
+ case 2: return B2;
+ case 3: return B3;
+ case 4: return B4;
+ case 5: return B5;
+ case 6: return B6;
+ case 7: return B7;
+ case 8: return B8;
+ case 9: return B9;
+ case 10: return B10;
+ case 11: return B11;
+ case 12: return B12;
+ case 13: return B13;
+ case 14: return B14;
+ case 15: return B15;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ public ushort ExtractUInt16(int Index)
+ {
+ switch (Index)
+ {
+ case 0: return H0;
+ case 1: return H1;
+ case 2: return H2;
+ case 3: return H3;
+ case 4: return H4;
+ case 5: return H5;
+ case 6: return H6;
+ case 7: return H7;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ public uint ExtractUInt32(int Index)
+ {
+ switch (Index)
+ {
+ case 0: return W0;
+ case 1: return W1;
+ case 2: return W2;
+ case 3: return W3;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ public float ExtractSingle(int Index)
+ {
+ switch (Index)
+ {
+ case 0: return S0;
+ case 1: return S1;
+ case 2: return S2;
+ case 3: return S3;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ public ulong ExtractUInt64(int Index)
+ {
+ switch (Index)
+ {
+ case 0: return X0;
+ case 1: return X1;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ public double ExtractDouble(int Index)
+ {
+ switch (Index)
+ {
+ case 0: return D0;
+ case 1: return D1;
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ public static AVec InsertByte(AVec Vec, int Index, byte Value)
+ {
+ switch (Index)
+ {
+ case 0: Vec.B0 = Value; break;
+ case 1: Vec.B1 = Value; break;
+ case 2: Vec.B2 = Value; break;
+ case 3: Vec.B3 = Value; break;
+ case 4: Vec.B4 = Value; break;
+ case 5: Vec.B5 = Value; break;
+ case 6: Vec.B6 = Value; break;
+ case 7: Vec.B7 = Value; break;
+ case 8: Vec.B8 = Value; break;
+ case 9: Vec.B9 = Value; break;
+ case 10: Vec.B10 = Value; break;
+ case 11: Vec.B11 = Value; break;
+ case 12: Vec.B12 = Value; break;
+ case 13: Vec.B13 = Value; break;
+ case 14: Vec.B14 = Value; break;
+ case 15: Vec.B15 = Value; break;
+
+ default: throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ return Vec;
+ }
+
+ public static AVec InsertUInt16(AVec Vec, int Index, ushort Value)
+ {
+ switch (Index)
+ {
+ case 0: Vec.H0 = Value; break;
+ case 1: Vec.H1 = Value; break;
+ case 2: Vec.H2 = Value; break;
+ case 3: Vec.H3 = Value; break;
+ case 4: Vec.H4 = Value; break;
+ case 5: Vec.H5 = Value; break;
+ case 6: Vec.H6 = Value; break;
+ case 7: Vec.H7 = Value; break;
+
+ default: throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ return Vec;
+ }
+
+ public static AVec InsertUInt32(AVec Vec, int Index, uint Value)
+ {
+ switch (Index)
+ {
+ case 0: Vec.W0 = Value; break;
+ case 1: Vec.W1 = Value; break;
+ case 2: Vec.W2 = Value; break;
+ case 3: Vec.W3 = Value; break;
+
+ default: throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ return Vec;
+ }
+
+ public static AVec InsertSingle(AVec Vec, int Index, float Value)
+ {
+ switch (Index)
+ {
+ case 0: Vec.S0 = Value; break;
+ case 1: Vec.S1 = Value; break;
+ case 2: Vec.S2 = Value; break;
+ case 3: Vec.S3 = Value; break;
+
+ default: throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ return Vec;
+ }
+
+ public static AVec InsertUInt64(AVec Vec, int Index, ulong Value)
+ {
+ switch (Index)
+ {
+ case 0: Vec.X0 = Value; break;
+ case 1: Vec.X1 = Value; break;
+
+ default: throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ return Vec;
+ }
+
+ public static AVec InsertDouble(AVec Vec, int Index, double Value)
+ {
+ switch (Index)
+ {
+ case 0: Vec.D0 = Value; break;
+ case 1: Vec.D1 = Value; break;
+
+ default: throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ return Vec;
+ }
+ }
+} \ No newline at end of file