diff options
| author | emmauss <emmausssss@gmail.com> | 2018-02-20 22:09:23 +0200 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-02-20 17:09:23 -0300 |
| commit | 62b827f474f0aa2152dd339fcc7cf31084e16a0b (patch) | |
| tree | 0e5c55b341aee4db0ccb841a084f253ec5e05657 /ChocolArm64/State | |
| parent | cb665bb715834526d73c9469d16114b287faaecd (diff) | |
Split main project into core,graphics and chocolarm4 subproject (#29)
Diffstat (limited to 'ChocolArm64/State')
| -rw-r--r-- | ChocolArm64/State/AInstExceptEventArgs.cs | 14 | ||||
| -rw-r--r-- | ChocolArm64/State/AInstUndEventArgs.cs | 16 | ||||
| -rw-r--r-- | ChocolArm64/State/APState.cs | 23 | ||||
| -rw-r--r-- | ChocolArm64/State/ARegister.cs | 142 | ||||
| -rw-r--r-- | ChocolArm64/State/ARegisterSize.cs | 10 | ||||
| -rw-r--r-- | ChocolArm64/State/ARegisterType.cs | 9 | ||||
| -rw-r--r-- | ChocolArm64/State/AThreadState.cs | 64 | ||||
| -rw-r--r-- | ChocolArm64/State/AVec.cs | 243 |
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 |
