예제 #1
0
 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));
     }
 }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
        }