aboutsummaryrefslogtreecommitdiff
path: root/ChocolArm64/Translation/ILEmitterCtx.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-02-04 18:26:05 -0300
committerGitHub <noreply@github.com>2019-02-04 18:26:05 -0300
commita694420d11ef74e4f0bf473be2b6f64635bc89c7 (patch)
tree6c44e7a0633dca7b54d99ac3f01f0648fa602559 /ChocolArm64/Translation/ILEmitterCtx.cs
parentf5b4f6ccc4815cfac1fa3c103d8941a26d152d8a (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/ILEmitterCtx.cs')
-rw-r--r--ChocolArm64/Translation/ILEmitterCtx.cs46
1 files changed, 25 insertions, 21 deletions
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<long, ILLabel> _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<Block, ILBlock> _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<long, ILLabel>();
_visitedBlocks = new Dictionary<Block, ILBlock>();
@@ -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)