aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Cpu/Jit/JitExecutionContext.cs
blob: f15486e68c254fc82379a47cf918f54dbcd97aca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using ARMeilleure.Memory;
using ARMeilleure.State;

namespace Ryujinx.Cpu.Jit
{
    class JitExecutionContext : IExecutionContext
    {
        private readonly ExecutionContext _impl;
        internal ExecutionContext Impl => _impl;

        /// <inheritdoc/>
        public ulong Pc => _impl.Pc;

        /// <inheritdoc/>
        public long TpidrEl0
        {
            get => _impl.TpidrEl0;
            set => _impl.TpidrEl0 = value;
        }

        /// <inheritdoc/>
        public long TpidrroEl0
        {
            get => _impl.TpidrroEl0;
            set => _impl.TpidrroEl0 = value;
        }

        /// <inheritdoc/>
        public uint Pstate
        {
            get => _impl.Pstate;
            set => _impl.Pstate = value;
        }

        /// <inheritdoc/>
        public uint Fpcr
        {
            get => (uint)_impl.Fpcr;
            set => _impl.Fpcr = (FPCR)value;
        }

        /// <inheritdoc/>
        public uint Fpsr
        {
            get => (uint)_impl.Fpsr;
            set => _impl.Fpsr = (FPSR)value;
        }

        /// <inheritdoc/>
        public bool IsAarch32
        {
            get => _impl.IsAarch32;
            set => _impl.IsAarch32 = value;
        }

        /// <inheritdoc/>
        public bool Running => _impl.Running;

        private readonly ExceptionCallbacks _exceptionCallbacks;

        public JitExecutionContext(IJitMemoryAllocator allocator, ICounter counter, ExceptionCallbacks exceptionCallbacks)
        {
            _impl = new ExecutionContext(
                allocator,
                counter,
                InterruptHandler,
                BreakHandler,
                SupervisorCallHandler,
                UndefinedHandler);

            _exceptionCallbacks = exceptionCallbacks;
        }

        /// <inheritdoc/>
        public ulong GetX(int index) => _impl.GetX(index);

        /// <inheritdoc/>
        public void SetX(int index, ulong value) => _impl.SetX(index, value);

        /// <inheritdoc/>
        public V128 GetV(int index) => _impl.GetV(index);

        /// <inheritdoc/>
        public void SetV(int index, V128 value) => _impl.SetV(index, value);

        private void InterruptHandler(ExecutionContext context)
        {
            _exceptionCallbacks.InterruptCallback?.Invoke(this);
        }

        private void BreakHandler(ExecutionContext context, ulong address, int imm)
        {
            _exceptionCallbacks.BreakCallback?.Invoke(this, address, imm);
        }

        private void SupervisorCallHandler(ExecutionContext context, ulong address, int imm)
        {
            _exceptionCallbacks.SupervisorCallback?.Invoke(this, address, imm);
        }

        private void UndefinedHandler(ExecutionContext context, ulong address, int opCode)
        {
            _exceptionCallbacks.UndefinedCallback?.Invoke(this, address, opCode);
        }

        /// <inheritdoc/>
        public void RequestInterrupt()
        {
            _impl.RequestInterrupt();
        }

        /// <inheritdoc/>
        public void StopRunning()
        {
            _impl.StopRunning();
        }

        public void Dispose()
        {
            _impl.Dispose();
        }
    }
}