示例#1
0
        public ILEmitterCtx(
            MemoryManager memory,
            TranslatorCache cache,
            TranslatorQueue queue,
            TranslationTier tier,
            Block graph)
        {
            Memory     = memory ?? throw new ArgumentNullException(nameof(memory));
            _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>();

            _visitedBlocks.Add(graph, new ILBlock());

            _branchTargets = new Queue <Block>();

            _ilBlocks = new List <ILBlock>();

            _subPosition = graph.Position;

            ResetBlockState();

            if (AdvanceOpCode())
            {
                EmitSynchronization();

                _ilBlock.Add(new ILOpCodeLoadState(_ilBlock, isSubEntry: true));
            }
        }
示例#2
0
        private void EmitOpCode()
        {
            if (_currBlock == null)
            {
                return;
            }

            if (_opcIndex == 0)
            {
                MarkLabel(GetLabel(_currBlock.Position));

                EmitSynchronization();
            }

            //On AARCH32 mode, (almost) all instruction can be conditionally
            //executed, and the required condition is encoded on the opcode.
            //We handle that here, skipping the instruction if the condition
            //is not met. We can just ignore it when the condition is "Always",
            //because in this case the instruction is always going to be executed.
            //Condition "Never" is also ignored because this is a special encoding
            //used by some unconditional instructions.
            ILLabel lblSkip = null;

            if (CurrOp is OpCode32 op && op.Cond < Condition.Al)
            {
                lblSkip = new ILLabel();

                EmitCondBranch(lblSkip, GetInverseCond(op.Cond));
            }

            CurrOp.Emitter(this);

            if (lblSkip != null)
            {
                MarkLabel(lblSkip);

                //If this is the last op on the block, and there's no "next" block
                //after this one, then we have to return right now, with the address
                //of the next instruction to be executed (in the case that the condition
                //is false, and the branch was not taken, as all basic blocks should end with
                //some kind of branch).
                if (CurrOp == CurrBlock.GetLastOp() && CurrBlock.Next == null)
                {
                    EmitStoreState();
                    EmitLdc_I8(CurrOp.Position + CurrOp.OpCodeSizeInBytes);

                    Emit(OpCodes.Ret);
                }
            }

            _ilBlock.Add(new ILBarrier());
        }
示例#3
0
        public void EmitOpCode()
        {
            if (_opcIndex == 0)
            {
                MarkLabel(GetLabel(CurrBlock.Position));

                EmitSynchronization();
            }

            CurrOp.Emitter(this);

            _ilBlock.Add(new ILBarrier());
        }
示例#4
0
        private void EmitOpCode()
        {
            if (_currBlock == null)
            {
                return;
            }

            if (_opcIndex == 0)
            {
                MarkLabel(GetLabel(_currBlock.Position));

                EmitSynchronization();
            }

            CurrOp.Emitter(this);

            _ilBlock.Add(new ILBarrier());
        }