mirror of
				https://github.com/Ryujinx/Ryujinx.git
				synced 2025-10-24 18:20:31 -07:00 
			
		
		
		
	* Add AddressTable<T>
* Use AddressTable<T> for dispatch
* Remove JumpTable & co.
* Add fallback for out of range addresses
* Add PPTC support
* Add documentation to `AddressTable<T>`
* Make AddressTable<T> configurable
* Fix table walk
* Fix IsMapped check
* Remove CountTableCapacity
* Add PPTC support for fast path
* Rename IsMapped to IsValid
* Remove stale comment
* Change format of address in exception message
* Add TranslatorStubs
* Split DispatchStub
Avoids recompilation of stubs during tests.
* Add hint for 64bit or 32bit
* Add documentation to `Symbol`
* Add documentation to `TranslatorStubs`
Make `TranslatorStubs` disposable as well.
* Add documentation to `SymbolType`
* Add `AddressTableEventSource` to monitor function table size
Add an EventSource which measures the amount of unmanaged bytes
allocated by AddressTable<T> instances.
 dotnet-counters monitor -n Ryujinx --counters ARMeilleure
* Add `AllowLcqInFunctionTable` optimization toggle
This is to reduce the impact this change has on the test duration.
Before everytime a test was ran, the FunctionTable would be initialized
and populated so that the newly compiled test would get registered to
it.
* Implement unmanaged dispatcher
Uses the DispatchStub to dispatch into the next translation, which
allows execution to stay in unmanaged for longer and skips a
ConcurrentDictionary look up when the target translation has been
registered to the FunctionTable.
* Remove redundant null check
* Tune levels of FunctionTable
Uses 5 levels instead of 4 and change unit of AddressTableEventSource
from KB to MB.
* Use 64-bit function table
Improves codegen for direct branches:
    mov qword [rax+0x408],0x10603560
 -  mov rcx,sub_10603560_OFFSET
 -  mov ecx,[rcx]
 -  mov ecx,ecx
 -  mov rdx,JIT_CACHE_BASE
 -  add rdx,rcx
 +  mov rcx,sub_10603560
 +  mov rdx,[rcx]
    mov rcx,rax
Improves codegen for dispatch stub:
    and rax,byte +0x1f
 -  mov eax,[rcx+rax*4]
 -  mov eax,eax
 -  mov rcx,JIT_CACHE_BASE
 -  lea rax,[rcx+rax]
 +  mov rax,[rcx+rax*8]
    mov rcx,rbx
* Remove `JitCacheSymbol` & `JitCache.Offset`
* Turn `Translator.Translate` into an instance method
We do not have to add more parameter to this method and related ones as
new structures are added & needed for translation.
* Add symbol only when PTC is enabled
Address LDj3SNuD's feedback
* Change `NativeContext.Running` to a 32-bit integer
* Fix PageTable symbol for host mapped
		
	
		
			
				
	
	
		
			153 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using ARMeilleure.Memory;
 | |
| using System;
 | |
| using System.Diagnostics;
 | |
| 
 | |
| namespace ARMeilleure.State
 | |
| {
 | |
|     public class ExecutionContext
 | |
|     {
 | |
|         private const int MinCountForCheck = 4000;
 | |
| 
 | |
|         private NativeContext _nativeContext;
 | |
| 
 | |
|         internal IntPtr NativeContextPtr => _nativeContext.BasePtr;
 | |
| 
 | |
|         private bool _interrupted;
 | |
| 
 | |
|         private static Stopwatch _tickCounter;
 | |
| 
 | |
|         private static double _hostTickFreq;
 | |
| 
 | |
|         public uint CtrEl0   => 0x8444c004;
 | |
|         public uint DczidEl0 => 0x00000004;
 | |
| 
 | |
|         public ulong CntfrqEl0 { get; set; }
 | |
|         public ulong CntpctEl0
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 double ticks = _tickCounter.ElapsedTicks * _hostTickFreq;
 | |
| 
 | |
|                 return (ulong)(ticks * CntfrqEl0);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // CNTVCT_EL0 = CNTPCT_EL0 - CNTVOFF_EL2
 | |
|         // Since EL2 isn't implemented, CNTVOFF_EL2 = 0
 | |
|         public ulong CntvctEl0 => CntpctEl0;
 | |
| 
 | |
|         public static TimeSpan ElapsedTime => _tickCounter.Elapsed;
 | |
|         public static long ElapsedTicks => _tickCounter.ElapsedTicks;
 | |
|         public static double TickFrequency => _hostTickFreq;
 | |
| 
 | |
|         public long TpidrEl0 { get; set; }
 | |
|         public long Tpidr    { get; set; }
 | |
| 
 | |
|         public FPCR Fpcr { get; set; }
 | |
|         public FPSR Fpsr { get; set; }
 | |
|         public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz;
 | |
| 
 | |
|         public bool IsAarch32 { get; set; }
 | |
| 
 | |
|         internal ExecutionMode ExecutionMode
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (IsAarch32)
 | |
|                 {
 | |
|                     return GetPstateFlag(PState.TFlag)
 | |
|                         ? ExecutionMode.Aarch32Thumb
 | |
|                         : ExecutionMode.Aarch32Arm;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     return ExecutionMode.Aarch64;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public bool Running
 | |
|         {
 | |
|             get => _nativeContext.GetRunning();
 | |
|             private set => _nativeContext.SetRunning(value);
 | |
|         }
 | |
| 
 | |
|         public event EventHandler<EventArgs>              Interrupt;
 | |
|         public event EventHandler<InstExceptionEventArgs> Break;
 | |
|         public event EventHandler<InstExceptionEventArgs> SupervisorCall;
 | |
|         public event EventHandler<InstUndefinedEventArgs> Undefined;
 | |
| 
 | |
|         static ExecutionContext()
 | |
|         {
 | |
|             _hostTickFreq = 1.0 / Stopwatch.Frequency;
 | |
| 
 | |
|             _tickCounter = new Stopwatch();
 | |
|             _tickCounter.Start();
 | |
|         }
 | |
| 
 | |
|         public ExecutionContext(IJitMemoryAllocator allocator)
 | |
|         {
 | |
|             _nativeContext = new NativeContext(allocator);
 | |
| 
 | |
|             Running = true;
 | |
| 
 | |
|             _nativeContext.SetCounter(MinCountForCheck);
 | |
|         }
 | |
| 
 | |
|         public ulong GetX(int index)              => _nativeContext.GetX(index);
 | |
|         public void  SetX(int index, ulong value) => _nativeContext.SetX(index, value);
 | |
| 
 | |
|         public V128 GetV(int index)             => _nativeContext.GetV(index);
 | |
|         public void SetV(int index, V128 value) => _nativeContext.SetV(index, value);
 | |
| 
 | |
|         public bool GetPstateFlag(PState flag)             => _nativeContext.GetPstateFlag(flag);
 | |
|         public void SetPstateFlag(PState flag, bool value) => _nativeContext.SetPstateFlag(flag, value);
 | |
| 
 | |
|         public bool GetFPstateFlag(FPState flag) => _nativeContext.GetFPStateFlag(flag);
 | |
|         public void SetFPstateFlag(FPState flag, bool value) => _nativeContext.SetFPStateFlag(flag, value);
 | |
| 
 | |
|         internal void CheckInterrupt()
 | |
|         {
 | |
|             if (_interrupted)
 | |
|             {
 | |
|                 _interrupted = false;
 | |
| 
 | |
|                 Interrupt?.Invoke(this, EventArgs.Empty);
 | |
|             }
 | |
| 
 | |
|             _nativeContext.SetCounter(MinCountForCheck);
 | |
|         }
 | |
| 
 | |
|         public void RequestInterrupt()
 | |
|         {
 | |
|             _interrupted = true;
 | |
|         }
 | |
| 
 | |
|         internal void OnBreak(ulong address, int imm)
 | |
|         {
 | |
|             Break?.Invoke(this, new InstExceptionEventArgs(address, imm));
 | |
|         }
 | |
| 
 | |
|         internal void OnSupervisorCall(ulong address, int imm)
 | |
|         {
 | |
|             SupervisorCall?.Invoke(this, new InstExceptionEventArgs(address, imm));
 | |
|         }
 | |
| 
 | |
|         internal void OnUndefined(ulong address, int opCode)
 | |
|         {
 | |
|             Undefined?.Invoke(this, new InstUndefinedEventArgs(address, opCode));
 | |
|         }
 | |
| 
 | |
|         public void StopRunning()
 | |
|         {
 | |
|             Running = false;
 | |
| 
 | |
|             _nativeContext.SetCounter(0);
 | |
|         }
 | |
| 
 | |
|         public void Dispose()
 | |
|         {
 | |
|             _nativeContext.Dispose();
 | |
|         }
 | |
|     }
 | |
| } |