internal void TranslateVirtualSubroutine(CpuThreadState state, long position) { if (!_cache.TryGetSubroutine(position, out TranslatedSub sub) || sub.Tier == TranslationTier.Tier0) { _queue.Enqueue(new TranslatorQueueItem(position, state.GetExecutionMode(), TranslationTier.Tier1)); } }
public void TranslateAhead(long position, ExecutionMode mode = ExecutionMode.Aarch64) { if (_cache.TryGetSubroutine(position, out TranslatedSub sub) && sub.Tier != TranslationTier.Tier0) { return; } _queue.Enqueue(position, mode, TranslationTier.Tier1, isComplete: true); }
private void ExecuteSubroutine(CpuThreadState state, long position) { state.CurrentTranslator = this; do { if (EnableCpuTrace) { CpuTrace?.Invoke(this, new CpuTraceEventArgs(position)); } if (!_cache.TryGetSubroutine(position, out TranslatedSub sub)) { sub = TranslateLowCq(position, state.GetExecutionMode()); } position = sub.Execute(state, _memory); }while (position != 0 && state.Running); state.CurrentTranslator = null; }
public void Execute(ARMeilleure.State.IExecutionContext ctx, ulong address) { CpuThreadState state = (CpuThreadState)ctx; long position = (long)address; if (Interlocked.Increment(ref _threadCount) == 1) { _backgroundTranslator = new Thread(TranslateQueuedSubs); _backgroundTranslator.Start(); } state.CurrentTranslator = this; do { if (EnableCpuTrace) { CpuTrace?.Invoke(this, new CpuTraceEventArgs(position)); } if (!_cache.TryGetSubroutine(position, out TranslatedSub sub)) { sub = TranslateLowCq(position, state.GetExecutionMode()); } position = sub.Execute(state, _memory); }while (position != 0 && state.Running); state.CurrentTranslator = null; if (Interlocked.Decrement(ref _threadCount) == 0) { _queue.ForceSignal(); } }
public bool TryOptEmitSubroutineCall() { if (CurrBlock.Next == null) { return(false); } if (CurrOp.Emitter != InstEmit.Bl) { return(false); } if (!_cache.TryGetSubroutine(((OpCodeBImmAl64)CurrOp).Imm, out TranslatedSub subroutine)) { return(false); } for (int index = 0; index < TranslatedSub.FixedArgTypes.Length; index++) { EmitLdarg(index); } foreach (Register reg in subroutine.Params) { 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(_root.Position); return(true); }