Пример #1
0
        private void EmitOpCode()
        {
            if (_currBlock == null)
            {
                return;
            }

            int opcIndex = _opcIndex;

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

            bool isLastOp = opcIndex == CurrBlock.OpCodes.Count - 1;

            if (isLastOp && CurrBlock.Branch != null &&
                (ulong)CurrBlock.Branch.Position <= (ulong)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 (isLastOp && CurrBlock.Next == null)
                {
                    EmitStoreState();
                    EmitLdc_I8(CurrOp.Position + CurrOp.OpCodeSizeInBytes);

                    Emit(OpCodes.Ret);
                }
            }

            _ilBlock.Add(new ILBarrier());
        }
Пример #2
0
        public void EmitRor(int amount)
        {
            if (amount > 0)
            {
                Stloc(RorTmpIndex, VarType.Int);
                Ldloc(RorTmpIndex, VarType.Int);

                EmitLdc_I4(amount);

                Emit(OpCodes.Shr_Un);

                Ldloc(RorTmpIndex, VarType.Int);

                EmitLdc_I4(CurrOp.GetBitsCount() - amount);

                Emit(OpCodes.Shl);
                Emit(OpCodes.Or);
            }
        }