diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-02-04 18:26:05 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-02-04 18:26:05 -0300 |
| commit | a694420d11ef74e4f0bf473be2b6f64635bc89c7 (patch) | |
| tree | 6c44e7a0633dca7b54d99ac3f01f0648fa602559 /ChocolArm64/Translation/TranslatedSub.cs | |
| parent | f5b4f6ccc4815cfac1fa3c103d8941a26d152d8a (diff) | |
Implement speculative translation on the CPU (#515)
* Implement speculative translation on the cpu, and change the way how branches to unknown or untranslated addresses works
* Port t0opt changes and other cleanups
* Change namespace from translation related classes to ChocolArm64.Translation, other minor tweaks
* Fix typo
* Translate higher quality code for indirect jumps aswell, and on some cases that were missed when lower quality (tier 0) code was available
* Remove debug print
* Remove direct argument passing optimization, and enable tail calls for BR instructions
* Call delegates directly with Callvirt rather than calling Execute, do not emit calls for tier 0 code
* Remove unused property
* Rename argument on ArmSubroutine delegate
Diffstat (limited to 'ChocolArm64/Translation/TranslatedSub.cs')
| -rw-r--r-- | ChocolArm64/Translation/TranslatedSub.cs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/ChocolArm64/Translation/TranslatedSub.cs b/ChocolArm64/Translation/TranslatedSub.cs new file mode 100644 index 00000000..65d70351 --- /dev/null +++ b/ChocolArm64/Translation/TranslatedSub.cs @@ -0,0 +1,65 @@ +using ChocolArm64.Memory; +using ChocolArm64.State; +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace ChocolArm64.Translation +{ + delegate long ArmSubroutine(CpuThreadState state, MemoryManager memory); + + class TranslatedSub + { + public ArmSubroutine Delegate { get; private set; } + + public static int StateArgIdx { get; private set; } + public static int MemoryArgIdx { get; private set; } + + public static Type[] FixedArgTypes { get; private set; } + + public DynamicMethod Method { get; private set; } + + public TranslationTier Tier { get; private set; } + + public TranslatedSub(DynamicMethod method, TranslationTier tier) + { + Method = method ?? throw new ArgumentNullException(nameof(method));; + Tier = tier; + } + + static TranslatedSub() + { + MethodInfo mthdInfo = typeof(ArmSubroutine).GetMethod("Invoke"); + + ParameterInfo[] Params = mthdInfo.GetParameters(); + + FixedArgTypes = new Type[Params.Length]; + + for (int index = 0; index < Params.Length; index++) + { + Type argType = Params[index].ParameterType; + + FixedArgTypes[index] = argType; + + if (argType == typeof(CpuThreadState)) + { + StateArgIdx = index; + } + else if (argType == typeof(MemoryManager)) + { + MemoryArgIdx = index; + } + } + } + + public void PrepareMethod() + { + Delegate = (ArmSubroutine)Method.CreateDelegate(typeof(ArmSubroutine)); + } + + public long Execute(CpuThreadState threadState, MemoryManager memory) + { + return Delegate(threadState, memory); + } + } +}
\ No newline at end of file |
