diff options
Diffstat (limited to 'ChocolArm64')
-rw-r--r-- | ChocolArm64/ChocolArm64.csproj | 3 | ||||
-rw-r--r-- | ChocolArm64/CpuThread.cs | 66 | ||||
-rw-r--r-- | ChocolArm64/Instructions/InstEmitMemoryHelper.cs | 10 | ||||
-rw-r--r-- | ChocolArm64/Instructions/InstEmitSystem.cs | 8 | ||||
-rw-r--r-- | ChocolArm64/Instructions/SoftFloat.cs | 112 | ||||
-rw-r--r-- | ChocolArm64/Memory/MemoryManager.cs | 10 | ||||
-rw-r--r-- | ChocolArm64/Optimizations.cs | 35 | ||||
-rw-r--r-- | ChocolArm64/State/CpuThreadState.cs | 187 | ||||
-rw-r--r-- | ChocolArm64/Translation/Translator.cs | 23 |
9 files changed, 275 insertions, 179 deletions
diff --git a/ChocolArm64/ChocolArm64.csproj b/ChocolArm64/ChocolArm64.csproj index ea98003f..cccdd94d 100644 --- a/ChocolArm64/ChocolArm64.csproj +++ b/ChocolArm64/ChocolArm64.csproj @@ -2,7 +2,7 @@ <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> - <RuntimeIdentifiers>win10-x64;osx-x64;linux-x64</RuntimeIdentifiers> + <RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers> <Configurations>Debug;Release;Profile Debug;Profile Release</Configurations> </PropertyGroup> @@ -33,6 +33,7 @@ <ItemGroup> <ProjectReference Include="..\Ryujinx.Profiler\Ryujinx.Profiler.csproj" /> + <ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" /> </ItemGroup> </Project> diff --git a/ChocolArm64/CpuThread.cs b/ChocolArm64/CpuThread.cs deleted file mode 100644 index ad1fd6f3..00000000 --- a/ChocolArm64/CpuThread.cs +++ /dev/null @@ -1,66 +0,0 @@ -using ChocolArm64.Memory; -using ChocolArm64.State; -using ChocolArm64.Translation; -using System; -using System.Threading; - -namespace ChocolArm64 -{ - public class CpuThread - { - public CpuThreadState ThreadState { get; private set; } - public MemoryManager Memory { get; private set; } - - private Translator _translator; - - public Thread Work; - - public event EventHandler WorkFinished; - - private int _isExecuting; - - public CpuThread(Translator translator, MemoryManager memory, long entrypoint) - { - _translator = translator; - Memory = memory; - - ThreadState = new CpuThreadState(); - - ThreadState.Running = true; - - Work = new Thread(delegate() - { - translator.ExecuteSubroutine(this, entrypoint); - - WorkFinished?.Invoke(this, EventArgs.Empty); - }); - } - - public bool Execute() - { - if (Interlocked.Exchange(ref _isExecuting, 1) == 1) - { - return false; - } - - Work.Start(); - - return true; - } - - public void StopExecution() - { - ThreadState.Running = false; - } - - public void RequestInterrupt() - { - ThreadState.RequestInterrupt(); - } - - public bool IsCurrentThread() - { - return Thread.CurrentThread == Work; - } - } -}
\ No newline at end of file diff --git a/ChocolArm64/Instructions/InstEmitMemoryHelper.cs b/ChocolArm64/Instructions/InstEmitMemoryHelper.cs index dbb58886..08c8265b 100644 --- a/ChocolArm64/Instructions/InstEmitMemoryHelper.cs +++ b/ChocolArm64/Instructions/InstEmitMemoryHelper.cs @@ -462,11 +462,11 @@ namespace ChocolArm64.Instructions switch (size) { - case 0: fallbackMethodName = nameof(MemoryManager.WriteVector8); break; - case 1: fallbackMethodName = nameof(MemoryManager.WriteVector16); break; - case 2: fallbackMethodName = nameof(MemoryManager.WriteVector32); break; - case 3: fallbackMethodName = nameof(MemoryManager.WriteVector64); break; - case 4: fallbackMethodName = nameof(MemoryManager.WriteVector128); break; + case 0: fallbackMethodName = nameof(MemoryManager.WriteVector8); break; + case 1: fallbackMethodName = nameof(MemoryManager.WriteVector16); break; + case 2: fallbackMethodName = nameof(MemoryManager.WriteVector32); break; + case 3: fallbackMethodName = nameof(MemoryManager.WriteVector64); break; + case 4: fallbackMethodName = nameof(MemoryManager.WriteVector128Internal); break; } context.EmitCall(typeof(MemoryManager), fallbackMethodName); diff --git a/ChocolArm64/Instructions/InstEmitSystem.cs b/ChocolArm64/Instructions/InstEmitSystem.cs index d0d60b9d..ac264de9 100644 --- a/ChocolArm64/Instructions/InstEmitSystem.cs +++ b/ChocolArm64/Instructions/InstEmitSystem.cs @@ -31,8 +31,8 @@ namespace ChocolArm64.Instructions { case 0b11_011_0000_0000_001: propName = nameof(CpuThreadState.CtrEl0); break; case 0b11_011_0000_0000_111: propName = nameof(CpuThreadState.DczidEl0); break; - case 0b11_011_0100_0100_000: propName = nameof(CpuThreadState.Fpcr); break; - case 0b11_011_0100_0100_001: propName = nameof(CpuThreadState.Fpsr); break; + case 0b11_011_0100_0100_000: propName = nameof(CpuThreadState.CFpcr); break; + case 0b11_011_0100_0100_001: propName = nameof(CpuThreadState.CFpsr); break; case 0b11_011_1101_0000_010: propName = nameof(CpuThreadState.TpidrEl0); break; case 0b11_011_1101_0000_011: propName = nameof(CpuThreadState.Tpidr); break; case 0b11_011_1110_0000_000: propName = nameof(CpuThreadState.CntfrqEl0); break; @@ -65,8 +65,8 @@ namespace ChocolArm64.Instructions switch (GetPackedId(op)) { - case 0b11_011_0100_0100_000: propName = nameof(CpuThreadState.Fpcr); break; - case 0b11_011_0100_0100_001: propName = nameof(CpuThreadState.Fpsr); break; + case 0b11_011_0100_0100_000: propName = nameof(CpuThreadState.CFpcr); break; + case 0b11_011_0100_0100_001: propName = nameof(CpuThreadState.CFpsr); break; case 0b11_011_1101_0000_010: propName = nameof(CpuThreadState.TpidrEl0); break; default: throw new NotImplementedException($"Unknown MSR at {op.Position:x16}"); diff --git a/ChocolArm64/Instructions/SoftFloat.cs b/ChocolArm64/Instructions/SoftFloat.cs index 3521ad15..e78932cc 100644 --- a/ChocolArm64/Instructions/SoftFloat.cs +++ b/ChocolArm64/Instructions/SoftFloat.cs @@ -82,7 +82,7 @@ namespace ChocolArm64.Instructions { public static float FPConvert(ushort valueBits, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat16_32.FPConvert: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat16_32.FPConvert: state.Fpcr = 0x{state.CFpcr:X8}"); double real = valueBits.FPUnpackCv(out FpType type, out bool sign, state); @@ -322,13 +322,13 @@ namespace ChocolArm64.Instructions { int enable = (int)exc + 8; - if ((state.Fpcr & (1 << enable)) != 0) + if ((state.CFpcr & (1 << enable)) != 0) { throw new NotImplementedException("Floating-point trap handling."); } else { - state.Fpsr |= 1 << (int)exc; + state.CFpsr |= 1 << (int)exc; } } } @@ -337,7 +337,7 @@ namespace ChocolArm64.Instructions { public static ushort FPConvert(float value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32_16.FPConvert: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32_16.FPConvert: state.Fpcr = 0x{state.CFpcr:X8}"); double real = value.FPUnpackCv(out FpType type, out bool sign, out uint valueBits, state); @@ -609,13 +609,13 @@ namespace ChocolArm64.Instructions { int enable = (int)exc + 8; - if ((state.Fpcr & (1 << enable)) != 0) + if ((state.CFpcr & (1 << enable)) != 0) { throw new NotImplementedException("Floating-point trap handling."); } else { - state.Fpsr |= 1 << (int)exc; + state.CFpsr |= 1 << (int)exc; } } } @@ -624,7 +624,7 @@ namespace ChocolArm64.Instructions { public static float FPAdd(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPAdd: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPAdd: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state); @@ -672,7 +672,7 @@ namespace ChocolArm64.Instructions public static int FPCompare(float value1, float value2, bool signalNaNs, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPCompare: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompare: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out _, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out _, state); @@ -709,7 +709,7 @@ namespace ChocolArm64.Instructions public static float FPCompareEQ(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPCompareEQ: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareEQ: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out _, out _, state); value2 = value2.FPUnpack(out FpType type2, out _, out _, state); @@ -735,7 +735,7 @@ namespace ChocolArm64.Instructions public static float FPCompareGE(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPCompareGE: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareGE: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out _, out _, state); value2 = value2.FPUnpack(out FpType type2, out _, out _, state); @@ -758,7 +758,7 @@ namespace ChocolArm64.Instructions public static float FPCompareGT(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPCompareGT: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareGT: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out _, out _, state); value2 = value2.FPUnpack(out FpType type2, out _, out _, state); @@ -782,7 +782,7 @@ namespace ChocolArm64.Instructions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float FPCompareLE(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPCompareLE: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareLE: state.Fpcr = 0x{state.CFpcr:X8}"); return FPCompareGE(value2, value1, state); } @@ -790,14 +790,14 @@ namespace ChocolArm64.Instructions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float FPCompareLT(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPCompareLT: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPCompareLT: state.Fpcr = 0x{state.CFpcr:X8}"); return FPCompareGT(value2, value1, state); } public static float FPDiv(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPDiv: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPDiv: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state); @@ -846,7 +846,7 @@ namespace ChocolArm64.Instructions public static float FPMax(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMax: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMax: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state); @@ -899,7 +899,7 @@ namespace ChocolArm64.Instructions public static float FPMaxNum(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMaxNum: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMaxNum: state.Fpcr = 0x{state.CFpcr:X8}"); value1.FPUnpack(out FpType type1, out _, out _, state); value2.FPUnpack(out FpType type2, out _, out _, state); @@ -918,7 +918,7 @@ namespace ChocolArm64.Instructions public static float FPMin(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMin: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMin: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state); @@ -971,7 +971,7 @@ namespace ChocolArm64.Instructions public static float FPMinNum(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMinNum: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMinNum: state.Fpcr = 0x{state.CFpcr:X8}"); value1.FPUnpack(out FpType type1, out _, out _, state); value2.FPUnpack(out FpType type2, out _, out _, state); @@ -990,7 +990,7 @@ namespace ChocolArm64.Instructions public static float FPMul(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMul: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMul: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state); @@ -1038,7 +1038,7 @@ namespace ChocolArm64.Instructions float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMulAdd: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMulAdd: state.Fpcr = 0x{state.CFpcr:X8}"); valueA = valueA.FPUnpack(out FpType typeA, out bool signA, out uint addend, state); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); @@ -1108,7 +1108,7 @@ namespace ChocolArm64.Instructions float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMulSub: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMulSub: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPNeg(); @@ -1117,7 +1117,7 @@ namespace ChocolArm64.Instructions public static float FPMulX(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPMulX: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPMulX: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state); @@ -1159,7 +1159,7 @@ namespace ChocolArm64.Instructions public static float FPRecipEstimate(float value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPRecipEstimate: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRecipEstimate: state.Fpcr = 0x{state.CFpcr:X8}"); value.FPUnpack(out FpType type, out bool sign, out uint op, state); @@ -1248,7 +1248,7 @@ namespace ChocolArm64.Instructions public static float FPRecipStepFused(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPRecipStepFused: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRecipStepFused: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPNeg(); @@ -1291,7 +1291,7 @@ namespace ChocolArm64.Instructions public static float FPRecpX(float value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPRecpX: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRecpX: state.Fpcr = 0x{state.CFpcr:X8}"); value.FPUnpack(out FpType type, out bool sign, out uint op, state); @@ -1315,7 +1315,7 @@ namespace ChocolArm64.Instructions public static float FPRSqrtEstimate(float value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPRSqrtEstimate: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRSqrtEstimate: state.Fpcr = 0x{state.CFpcr:X8}"); value.FPUnpack(out FpType type, out bool sign, out uint op, state); @@ -1380,7 +1380,7 @@ namespace ChocolArm64.Instructions public static float FPRSqrtStepFused(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPRSqrtStepFused: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPRSqrtStepFused: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPNeg(); @@ -1423,7 +1423,7 @@ namespace ChocolArm64.Instructions public static float FPSqrt(float value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPSqrt: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPSqrt: state.Fpcr = 0x{state.CFpcr:X8}"); value = value.FPUnpack(out FpType type, out bool sign, out uint op, state); @@ -1464,7 +1464,7 @@ namespace ChocolArm64.Instructions public static float FPSub(float value1, float value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat32.FPSub: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat32.FPSub: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out uint op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out uint op2, state); @@ -1693,13 +1693,13 @@ namespace ChocolArm64.Instructions { int enable = (int)exc + 8; - if ((state.Fpcr & (1 << enable)) != 0) + if ((state.CFpcr & (1 << enable)) != 0) { throw new NotImplementedException("Floating-point trap handling."); } else { - state.Fpsr |= 1 << (int)exc; + state.CFpsr |= 1 << (int)exc; } } } @@ -1708,7 +1708,7 @@ namespace ChocolArm64.Instructions { public static double FPAdd(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPAdd: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPAdd: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state); @@ -1756,7 +1756,7 @@ namespace ChocolArm64.Instructions public static int FPCompare(double value1, double value2, bool signalNaNs, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPCompare: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompare: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out _, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out _, state); @@ -1793,7 +1793,7 @@ namespace ChocolArm64.Instructions public static double FPCompareEQ(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPCompareEQ: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareEQ: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out _, out _, state); value2 = value2.FPUnpack(out FpType type2, out _, out _, state); @@ -1819,7 +1819,7 @@ namespace ChocolArm64.Instructions public static double FPCompareGE(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPCompareGE: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareGE: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out _, out _, state); value2 = value2.FPUnpack(out FpType type2, out _, out _, state); @@ -1842,7 +1842,7 @@ namespace ChocolArm64.Instructions public static double FPCompareGT(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPCompareGT: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareGT: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out _, out _, state); value2 = value2.FPUnpack(out FpType type2, out _, out _, state); @@ -1866,7 +1866,7 @@ namespace ChocolArm64.Instructions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double FPCompareLE(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPCompareLE: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareLE: state.Fpcr = 0x{state.CFpcr:X8}"); return FPCompareGE(value2, value1, state); } @@ -1874,14 +1874,14 @@ namespace ChocolArm64.Instructions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double FPCompareLT(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPCompareLT: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPCompareLT: state.Fpcr = 0x{state.CFpcr:X8}"); return FPCompareGT(value2, value1, state); } public static double FPDiv(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPDiv: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPDiv: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state); @@ -1930,7 +1930,7 @@ namespace ChocolArm64.Instructions public static double FPMax(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMax: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMax: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state); @@ -1983,7 +1983,7 @@ namespace ChocolArm64.Instructions public static double FPMaxNum(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMaxNum: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMaxNum: state.Fpcr = 0x{state.CFpcr:X8}"); value1.FPUnpack(out FpType type1, out _, out _, state); value2.FPUnpack(out FpType type2, out _, out _, state); @@ -2002,7 +2002,7 @@ namespace ChocolArm64.Instructions public static double FPMin(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMin: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMin: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state); @@ -2055,7 +2055,7 @@ namespace ChocolArm64.Instructions public static double FPMinNum(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMinNum: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMinNum: state.Fpcr = 0x{state.CFpcr:X8}"); value1.FPUnpack(out FpType type1, out _, out _, state); value2.FPUnpack(out FpType type2, out _, out _, state); @@ -2074,7 +2074,7 @@ namespace ChocolArm64.Instructions public static double FPMul(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMul: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMul: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state); @@ -2122,7 +2122,7 @@ namespace ChocolArm64.Instructions double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMulAdd: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMulAdd: state.Fpcr = 0x{state.CFpcr:X8}"); valueA = valueA.FPUnpack(out FpType typeA, out bool signA, out ulong addend, state); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); @@ -2192,7 +2192,7 @@ namespace ChocolArm64.Instructions double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMulSub: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMulSub: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPNeg(); @@ -2201,7 +2201,7 @@ namespace ChocolArm64.Instructions public static double FPMulX(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPMulX: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPMulX: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state); @@ -2243,7 +2243,7 @@ namespace ChocolArm64.Instructions public static double FPRecipEstimate(double value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPRecipEstimate: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRecipEstimate: state.Fpcr = 0x{state.CFpcr:X8}"); value.FPUnpack(out FpType type, out bool sign, out ulong op, state); @@ -2332,7 +2332,7 @@ namespace ChocolArm64.Instructions public static double FPRecipStepFused(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPRecipStepFused: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRecipStepFused: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPNeg(); @@ -2375,7 +2375,7 @@ namespace ChocolArm64.Instructions public static double FPRecpX(double value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPRecpX: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRecpX: state.Fpcr = 0x{state.CFpcr:X8}"); value.FPUnpack(out FpType type, out bool sign, out ulong op, state); @@ -2399,7 +2399,7 @@ namespace ChocolArm64.Instructions public static double FPRSqrtEstimate(double value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPRSqrtEstimate: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRSqrtEstimate: state.Fpcr = 0x{state.CFpcr:X8}"); value.FPUnpack(out FpType type, out bool sign, out ulong op, state); @@ -2464,7 +2464,7 @@ namespace ChocolArm64.Instructions public static double FPRSqrtStepFused(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPRSqrtStepFused: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPRSqrtStepFused: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPNeg(); @@ -2507,7 +2507,7 @@ namespace ChocolArm64.Instructions public static double FPSqrt(double value, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPSqrt: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPSqrt: state.Fpcr = 0x{state.CFpcr:X8}"); value = value.FPUnpack(out FpType type, out bool sign, out ulong op, state); @@ -2548,7 +2548,7 @@ namespace ChocolArm64.Instructions public static double FPSub(double value1, double value2, CpuThreadState state) { - Debug.WriteLineIf(state.Fpcr != 0, $"SoftFloat64.FPSub: state.Fpcr = 0x{state.Fpcr:X8}"); + Debug.WriteLineIf(state.CFpcr != 0, $"SoftFloat64.FPSub: state.Fpcr = 0x{state.CFpcr:X8}"); value1 = value1.FPUnpack(out FpType type1, out bool sign1, out ulong op1, state); value2 = value2.FPUnpack(out FpType type2, out bool sign2, out ulong op2, state); @@ -2777,13 +2777,13 @@ namespace ChocolArm64.Instructions { int enable = (int)exc + 8; - if ((state.Fpcr & (1 << enable)) != 0) + if ((state.CFpcr & (1 << enable)) != 0) { throw new NotImplementedException("Floating-point trap handling."); } else { - state.Fpsr |= 1 << (int)exc; + state.CFpsr |= 1 << (int)exc; } } } diff --git a/ChocolArm64/Memory/MemoryManager.cs b/ChocolArm64/Memory/MemoryManager.cs index 364f6b58..2347f1eb 100644 --- a/ChocolArm64/Memory/MemoryManager.cs +++ b/ChocolArm64/Memory/MemoryManager.cs @@ -11,7 +11,7 @@ using static ChocolArm64.Memory.MemoryManagement; namespace ChocolArm64.Memory { - public unsafe class MemoryManager : IMemory, IDisposable + public unsafe class MemoryManager : ARMeilleure.Memory.IMemoryManager { public const int PageBits = 12; public const int PageSize = 1 << PageBits; @@ -880,7 +880,7 @@ namespace ChocolArm64.Memory } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteVector128(long position, Vector128<float> value) + public void WriteVector128Internal(long position, Vector128<float> value) { if (Sse.IsSupported && (position & 15) == 0) { @@ -893,6 +893,12 @@ namespace ChocolArm64.Memory } } + public void WriteVector128(long position, ARMeilleure.State.V128 value) + { + WriteUInt64(position + 0, value.GetUInt64(0)); + WriteUInt64(position + 8, value.GetUInt64(1)); + } + public void WriteBytes(long position, byte[] data) { long endAddr = position + data.Length; diff --git a/ChocolArm64/Optimizations.cs b/ChocolArm64/Optimizations.cs index cbb8131f..24828ebf 100644 --- a/ChocolArm64/Optimizations.cs +++ b/ChocolArm64/Optimizations.cs @@ -1,24 +1,27 @@ using System.Runtime.Intrinsics.X86; -public static class Optimizations +namespace ChocolArm64 { - public static bool AssumeStrictAbiCompliance { get; set; } + public static class Optimizations + { + public static bool AssumeStrictAbiCompliance { get; set; } = true; - public static bool FastFP { get; set; } = true; + public static bool FastFP { get; set; } = true; - private const bool UseAllSseIfAvailable = true; + private const bool UseAllSseIfAvailable = true; - public static bool UseSseIfAvailable { get; set; } = UseAllSseIfAvailable; - public static bool UseSse2IfAvailable { get; set; } = UseAllSseIfAvailable; - public static bool UseSse3IfAvailable { get; set; } = UseAllSseIfAvailable; - public static bool UseSsse3IfAvailable { get; set; } = UseAllSseIfAvailable; - public static bool UseSse41IfAvailable { get; set; } = UseAllSseIfAvailable; - public static bool UseSse42IfAvailable { get; set; } = UseAllSseIfAvailable; + public static bool UseSseIfAvailable { get; set; } = UseAllSseIfAvailable; + public static bool UseSse2IfAvailable { get; set; } = UseAllSseIfAvailable; + public static bool UseSse3IfAvailable { get; set; } = UseAllSseIfAvailable; + public static bool UseSsse3IfAvailable { get; set; } = UseAllSseIfAvailable; + public static bool UseSse41IfAvailable { get; set; } = UseAllSseIfAvailable; + public static bool UseSse42IfAvailable { get; set; } = UseAllSseIfAvailable; - internal static bool UseSse => UseSseIfAvailable && Sse.IsSupported; - internal static bool UseSse2 => UseSse2IfAvailable && Sse2.IsSupported; - internal static bool UseSse3 => UseSse3IfAvailable && Sse3.IsSupported; - internal static bool UseSsse3 => UseSsse3IfAvailable && Ssse3.IsSupported; - internal static bool UseSse41 => UseSse41IfAvailable && Sse41.IsSupported; - internal static bool UseSse42 => UseSse42IfAvailable && Sse42.IsSupported; + internal static bool UseSse => UseSseIfAvailable && Sse.IsSupported; + internal static bool UseSse2 => UseSse2IfAvailable && Sse2.IsSupported; + internal static bool UseSse3 => UseSse3IfAvailable && Sse3.IsSupported; + internal static bool UseSsse3 => UseSsse3IfAvailable && Ssse3.IsSupported; + internal static bool UseSse41 => UseSse41IfAvailable && Sse41.IsSupported; + internal static bool UseSse42 => UseSse42IfAvailable && Sse42.IsSupported; + } }
\ No newline at end of file diff --git a/ChocolArm64/State/CpuThreadState.cs b/ChocolArm64/State/CpuThreadState.cs index 424f1725..e4baaefa 100644 --- a/ChocolArm64/State/CpuThreadState.cs +++ b/ChocolArm64/State/CpuThreadState.cs @@ -1,13 +1,14 @@ -using ChocolArm64.Events; using ChocolArm64.Translation; using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; +using static ChocolArm64.Instructions.VectorHelper; + namespace ChocolArm64.State { - public class CpuThreadState + public class CpuThreadState : ARMeilleure.State.IExecutionContext { private const int MinCountForCheck = 40000; @@ -24,7 +25,7 @@ namespace ChocolArm64.State V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30, V31; - public bool Aarch32; + public bool IsAarch32 { get; set; } public bool Thumb; public bool BigEndian; @@ -45,8 +46,20 @@ namespace ChocolArm64.State public long TpidrEl0 { get; set; } public long Tpidr { get; set; } - public int Fpcr { get; set; } - public int Fpsr { get; set; } + public int CFpcr { get; set; } + public int CFpsr { get; set; } + + public ARMeilleure.State.FPCR Fpcr + { + get => (ARMeilleure.State.FPCR)CFpcr; + set => CFpcr = (int)value; + } + + public ARMeilleure.State.FPSR Fpsr + { + get => (ARMeilleure.State.FPSR)CFpsr; + set => CFpsr = (int)value; + } public int Psr { @@ -73,10 +86,10 @@ namespace ChocolArm64.State } } - public event EventHandler<EventArgs> Interrupt; - public event EventHandler<InstExceptionEventArgs> Break; - public event EventHandler<InstExceptionEventArgs> SvcCall; - public event EventHandler<InstUndefinedEventArgs> Undefined; + public event EventHandler<EventArgs> Interrupt; + public event EventHandler<ARMeilleure.State.InstExceptionEventArgs> Break; + public event EventHandler<ARMeilleure.State.InstExceptionEventArgs> SupervisorCall; + public event EventHandler<ARMeilleure.State.InstUndefinedEventArgs> Undefined; private static Stopwatch _tickCounter; @@ -92,6 +105,8 @@ namespace ChocolArm64.State public CpuThreadState() { ClearExclusiveAddress(); + + Running = true; } static CpuThreadState() @@ -151,29 +166,165 @@ namespace ChocolArm64.State } } - internal void RequestInterrupt() + public ulong GetX(int index) + { + switch (index) + { + case 0: return X0; + case 1: return X1; + case 2: return X2; + case 3: return X3; + case 4: return X4; + case 5: return X5; + case 6: return X6; + case 7: return X7; + case 8: return X8; + case 9: return X9; + case 10: return X10; + case 11: return X11; + case 12: return X12; + case 13: return X13; + case 14: return X14; + case 15: return X15; + case 16: return X16; + case 17: return X17; + case 18: return X18; + case 19: return X19; + case 20: return X20; + case 21: return X21; + case 22: return X22; + case 23: return X23; + case 24: return X24; + case 25: return X25; + case 26: return X26; + case 27: return X27; + case 28: return X28; + case 29: return X29; + case 30: return X30; + case 31: return X31; + + default: throw new ArgumentOutOfRangeException(nameof(index)); + } + } + + public void SetX(int index, ulong value) + { + switch (index) + { + case 0: X0 = value; break; + case 1: X1 = value; break; + case 2: X2 = value; break; + case 3: X3 = value; break; + case 4: X4 = value; break; + case 5: X5 = value; break; + case 6: X6 = value; break; + case 7: X7 = value; break; + case 8: X8 = value; break; + case 9: X9 = value; break; + case 10: X10 = value; break; + case 11: X11 = value; break; + case 12: X12 = value; break; + case 13: X13 = value; break; + case 14: X14 = value; break; + case 15: X15 = value; break; + case 16: X16 = value; break; + case 17: X17 = value; break; + case 18: X18 = value; break; + case 19: X19 = value; break; + case 20: X20 = value; break; + case 21: X21 = value; break; + case 22: X22 = value; break; + case 23: X23 = value; break; + case 24: X24 = value; break; + case 25: X25 = value; break; + case 26: X26 = value; break; + case 27: X27 = value; break; + case 28: X28 = value; break; + case 29: X29 = value; break; + case 30: X30 = value; break; + case 31: X31 = value; break; + + default: throw new ArgumentOutOfRangeException(nameof(index)); + } + } + + public ARMeilleure.State.V128 GetV(int index) + { + switch (index) + { + case 0: return new ARMeilleure.State.V128(VectorExtractIntZx(V0, 0, 3), VectorExtractIntZx(V0, 1, 3)); + case 1: return new ARMeilleure.State.V128(VectorExtractIntZx(V1, 0, 3), VectorExtractIntZx(V1, 1, 3)); + case 2: return new ARMeilleure.State.V128(VectorExtractIntZx(V2, 0, 3), VectorExtractIntZx(V2, 1, 3)); + case 3: return new ARMeilleure.State.V128(VectorExtractIntZx(V3, 0, 3), VectorExtractIntZx(V3, 1, 3)); + case 4: return new ARMeilleure.State.V128(VectorExtractIntZx(V4, 0, 3), VectorExtractIntZx(V4, 1, 3)); + case 5: return new ARMeilleure.State.V128(VectorExtractIntZx(V5, 0, 3), VectorExtractIntZx(V5, 1, 3)); + case 6: return new ARMeilleure.State.V128(VectorExtractIntZx(V6, 0, 3), VectorExtractIntZx(V6, 1, 3)); + case 7: return new ARMeilleure.State.V128(VectorExtractIntZx(V7, 0, 3), VectorExtractIntZx(V7, 1, 3)); + case 8: return new ARMeilleure.State.V128(VectorExtractIntZx(V8, 0, 3), VectorExtractIntZx(V8, 1, 3)); + case 9: return new ARMeilleure.State.V128(VectorExtractIntZx(V9, 0, 3), VectorExtractIntZx(V9, 1, 3)); + case 10: return new ARMeilleure.State.V128(VectorExtractIntZx(V10, 0, 3), VectorExtractIntZx(V10, 1, 3)); + case 11: return new ARMeilleure.State.V128(VectorExtractIntZx(V11, 0, 3), VectorExtractIntZx(V11, 1, 3)); + case 12: return new ARMeilleure.State.V128(VectorExtractIntZx(V12, 0, 3), VectorExtractIntZx(V12, 1, 3)); + case 13: return new ARMeilleure.State.V128(VectorExtractIntZx(V13, 0, 3), VectorExtractIntZx(V13, 1, 3)); + case 14: return new ARMeilleure.State.V128(VectorExtractIntZx(V14, 0, 3), VectorExtractIntZx(V14, 1, 3)); + case 15: return new ARMeilleure.State.V128(VectorExtractIntZx(V15, 0, 3), VectorExtractIntZx(V15, 1, 3)); + case 16: return new ARMeilleure.State.V128(VectorExtractIntZx(V16, 0, 3), VectorExtractIntZx(V16, 1, 3)); + case 17: return new ARMeilleure.State.V128(VectorExtractIntZx(V17, 0, 3), VectorExtractIntZx(V17, 1, 3)); + case 18: return new ARMeilleure.State.V128(VectorExtractIntZx(V18, 0, 3), VectorExtractIntZx(V18, 1, 3)); + case 19: return new ARMeilleure.State.V128(VectorExtractIntZx(V19, 0, 3), VectorExtractIntZx(V19, 1, 3)); + case 20: return new ARMeilleure.State.V128(VectorExtractIntZx(V20, 0, 3), VectorExtractIntZx(V20, 1, 3)); + case 21: return new ARMeilleure.State.V128(VectorExtractIntZx(V21, 0, 3), VectorExtractIntZx(V21, 1, 3)); + case 22: return new ARMeilleure.State.V128(VectorExtractIntZx(V22, 0, 3), VectorExtractIntZx(V22, 1, 3)); + case 23: return new ARMeilleure.State.V128(VectorExtractIntZx(V23, 0, 3), VectorExtractIntZx(V23, 1, 3)); + case 24: return new ARMeilleure.State.V128(VectorExtractIntZx(V24, 0, 3), VectorExtractIntZx(V24, 1, 3)); + case 25: return new ARMeilleure.State.V128(VectorExtractIntZx(V25, 0, 3), VectorExtractIntZx(V25, 1, 3)); + case 26: return new ARMeilleure.State.V128(VectorExtractIntZx(V26, 0, 3), VectorExtractIntZx(V26, 1, 3)); + case 27: return new ARMeilleure.State.V128(VectorExtractIntZx(V27, 0, 3), VectorExtractIntZx(V27, 1, 3)); + case 28: return new ARMeilleure.State.V128(VectorExtractIntZx(V28, 0, 3), VectorExtractIntZx(V28, 1, 3)); + case 29: return new ARMeilleure.State.V128(VectorExtractIntZx(V29, 0, 3), VectorExtractIntZx(V29, 1, 3)); + case 30: return new ARMeilleure.State.V128(VectorExtractIntZx(V30, 0, 3), VectorExtractIntZx(V30, 1, 3)); + case 31: return new ARMeilleure.State.V128(VectorExtractIntZx(V31, 0, 3), VectorExtractIntZx(V31, 1, 3)); + + default: throw new ArgumentOutOfRangeException(nameof(index)); + } + } + + public bool GetPstateFlag(ARMeilleure.State.PState flag) + { + switch (flag) + { + case ARMeilleure.State.PState.NFlag: return Negative; + case ARMeilleure.State.PState.ZFlag: return Zero; + case ARMeilleure.State.PState.CFlag: return Carry; + case ARMeilleure.State.PState.VFlag: return Overflow; + + default: throw new ArgumentOutOfRangeException(nameof(flag)); + } + } + + public void RequestInterrupt() { _interrupted = true; } internal void OnBreak(long position, int imm) { - Break?.Invoke(this, new InstExceptionEventArgs(position, imm)); + Break?.Invoke(this, new ARMeilleure.State.InstExceptionEventArgs((ulong)position, imm)); } internal void OnSvcCall(long position, int imm) { - SvcCall?.Invoke(this, new InstExceptionEventArgs(position, imm)); + SupervisorCall?.Invoke(this, new ARMeilleure.State.InstExceptionEventArgs((ulong)position, imm)); } internal void OnUndefined(long position, int rawOpCode) { - Undefined?.Invoke(this, new InstUndefinedEventArgs(position, rawOpCode)); + Undefined?.Invoke(this, new ARMeilleure.State.InstUndefinedEventArgs((ulong)position, rawOpCode)); } internal ExecutionMode GetExecutionMode() { - if (!Aarch32) + if (!IsAarch32) { return ExecutionMode.Aarch64; } @@ -185,17 +336,19 @@ namespace ChocolArm64.State internal bool GetFpcrFlag(Fpcr flag) { - return (Fpcr & (1 << (int)flag)) != 0; + return (CFpcr & (1 << (int)flag)) != 0; } internal void SetFpsrFlag(Fpsr flag) { - Fpsr |= 1 << (int)flag; + CFpsr |= 1 << (int)flag; } internal RoundMode FPRoundingMode() { - return (RoundMode)((Fpcr >> (int)State.Fpcr.RMode) & 3); + return (RoundMode)((CFpcr >> (int)State.Fpcr.RMode) & 3); } + + public void Dispose() { } } } diff --git a/ChocolArm64/Translation/Translator.cs b/ChocolArm64/Translation/Translator.cs index 0803df09..ab8f474a 100644 --- a/ChocolArm64/Translation/Translator.cs +++ b/ChocolArm64/Translation/Translator.cs @@ -9,7 +9,7 @@ using System.Threading; namespace ChocolArm64.Translation { - public class Translator + public class Translator : ARMeilleure.Translation.ITranslator { private MemoryManager _memory; @@ -38,24 +38,18 @@ namespace ChocolArm64.Translation _queue = new TranslatorQueue(); } - internal void ExecuteSubroutine(CpuThread thread, long position) + public void Execute(ARMeilleure.State.IExecutionContext ctx, ulong address) { + CpuThreadState state = (CpuThreadState)ctx; + + long position = (long)address; + if (Interlocked.Increment(ref _threadCount) == 1) { _backgroundTranslator = new Thread(TranslateQueuedSubs); _backgroundTranslator.Start(); } - ExecuteSubroutine(thread.ThreadState, position); - - if (Interlocked.Decrement(ref _threadCount) == 0) - { - _queue.ForceSignal(); - } - } - - private void ExecuteSubroutine(CpuThreadState state, long position) - { state.CurrentTranslator = this; do @@ -75,6 +69,11 @@ namespace ChocolArm64.Translation while (position != 0 && state.Running); state.CurrentTranslator = null; + + if (Interlocked.Decrement(ref _threadCount) == 0) + { + _queue.ForceSignal(); + } } internal ArmSubroutine GetOrTranslateSubroutine(CpuThreadState state, long position, CallType cs) |