From a694420d11ef74e4f0bf473be2b6f64635bc89c7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 4 Feb 2019 18:26:05 -0300 Subject: 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 --- ChocolArm64/Translation/ILEmitterCtx.cs | 46 ++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'ChocolArm64/Translation/ILEmitterCtx.cs') diff --git a/ChocolArm64/Translation/ILEmitterCtx.cs b/ChocolArm64/Translation/ILEmitterCtx.cs index b5ebff75..ef63e60c 100644 --- a/ChocolArm64/Translation/ILEmitterCtx.cs +++ b/ChocolArm64/Translation/ILEmitterCtx.cs @@ -11,6 +11,7 @@ namespace ChocolArm64.Translation class ILEmitterCtx { private TranslatorCache _cache; + private TranslatorQueue _queue; private Dictionary _labels; @@ -23,6 +24,8 @@ namespace ChocolArm64.Translation public Block CurrBlock => _currBlock; public OpCode64 CurrOp => _currBlock?.OpCodes[_opcIndex]; + public TranslationTier Tier { get; } + public Aarch32Mode Mode { get; } = Aarch32Mode.User; //TODO private Dictionary _visitedBlocks; @@ -47,11 +50,14 @@ namespace ChocolArm64.Translation private const int VecTmp1Index = -5; private const int VecTmp2Index = -6; - public ILEmitterCtx(TranslatorCache cache, Block graph) + public ILEmitterCtx(TranslatorCache cache, TranslatorQueue queue, TranslationTier tier, Block graph) { _cache = cache ?? throw new ArgumentNullException(nameof(cache)); + _queue = queue ?? throw new ArgumentNullException(nameof(queue)); _currBlock = graph ?? throw new ArgumentNullException(nameof(graph)); + Tier = tier; + _labels = new Dictionary(); _visitedBlocks = new Dictionary(); @@ -243,6 +249,16 @@ namespace ChocolArm64.Translation return new ILBlock(); } + public void TranslateAhead(long position, ExecutionMode mode = ExecutionMode.Aarch64) + { + if (_cache.TryGetSubroutine(position, out TranslatedSub sub) && sub.Tier != TranslationTier.Tier0) + { + return; + } + + _queue.Enqueue(new TranslatorQueueItem(position, mode, TranslationTier.Tier1)); + } + public bool TryOptEmitSubroutineCall() { if (_currBlock.Next == null) @@ -265,20 +281,8 @@ namespace ChocolArm64.Translation EmitLdarg(index); } - foreach (Register reg in subroutine.SubArgs) - { - switch (reg.Type) - { - case RegisterType.Flag: Ldloc(reg.Index, IoType.Flag); break; - case RegisterType.Int: Ldloc(reg.Index, IoType.Int); break; - case RegisterType.Vector: Ldloc(reg.Index, IoType.Vector); break; - } - } - EmitCall(subroutine.Method); - subroutine.AddCaller(_subPosition); - return true; } @@ -463,7 +467,12 @@ namespace ChocolArm64.Translation _ilBlock.Add(new ILOpCodeBranch(ilOp, label)); } - public void Emit(string text) + public void EmitFieldLoad(FieldInfo info) + { + _ilBlock.Add(new ILOpCodeLoadField(info)); + } + + public void EmitPrint(string text) { _ilBlock.Add(new ILOpCodeLog(text)); } @@ -618,14 +627,9 @@ namespace ChocolArm64.Translation EmitCall(objType.GetMethod(mthdName, BindingFlags.Instance | BindingFlags.NonPublic)); } - public void EmitCall(MethodInfo mthdInfo) + public void EmitCall(MethodInfo mthdInfo, bool isVirtual = false) { - if (mthdInfo == null) - { - throw new ArgumentNullException(nameof(mthdInfo)); - } - - _ilBlock.Add(new ILOpCodeCall(mthdInfo)); + _ilBlock.Add(new ILOpCodeCall(mthdInfo ?? throw new ArgumentNullException(nameof(mthdInfo)), isVirtual)); } public void EmitLdc_I(long value) -- cgit v1.2.3