예제 #1
0
        private static void EmitSimdMemWBack(ILEmitterCtx context, int offset)
        {
            OpCodeMemReg64 op = (OpCodeMemReg64)context.CurrOp;

            context.EmitLdint(op.Rn);

            if (op.Rm != RegisterAlias.Zr)
            {
                context.EmitLdint(op.Rm);
            }
            else
            {
                context.EmitLdc_I8(offset);
            }

            context.Emit(OpCodes.Add);

            context.EmitStint(op.Rn);
        }
예제 #2
0
        private static void EmitAluStore(ILEmitterCtx context)
        {
            IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;

            if (op.Rd == RegisterAlias.Aarch32Pc)
            {
                if (op.SetFlags)
                {
                    // TODO: Load SPSR etc.

                    context.EmitLdflg((int)PState.TBit);

                    ILLabel lblThumb = new ILLabel();
                    ILLabel lblEnd   = new ILLabel();

                    context.Emit(OpCodes.Brtrue_S, lblThumb);

                    context.EmitLdc_I4(~3);

                    context.Emit(OpCodes.Br_S, lblEnd);

                    context.MarkLabel(lblThumb);

                    context.EmitLdc_I4(~1);

                    context.MarkLabel(lblEnd);

                    context.Emit(OpCodes.And);
                    context.Emit(OpCodes.Conv_U8);
                    context.Emit(OpCodes.Ret);
                }
                else
                {
                    EmitAluWritePc(context);
                }
            }
            else
            {
                context.EmitStint(GetRegisterAlias(context.Mode, op.Rd));
            }
        }
예제 #3
0
        public static void Bl(ILEmitterCtx context)
        {
            OpCodeBImmAl64 op = (OpCodeBImmAl64)context.CurrOp;

            context.EmitLdc_I(op.Position + 4);
            context.EmitStint(CpuThreadState.LrIndex);
            context.EmitStoreState();

            if (context.TryOptEmitSubroutineCall())
            {
                //Note: the return value of the called method will be placed
                //at the Stack, the return value is always a Int64 with the
                //return address of the function. We check if the address is
                //correct, if it isn't we keep returning until we reach the dispatcher.
                context.Emit(OpCodes.Dup);

                context.EmitLdc_I8(op.Position + 4);

                ILLabel lblContinue = new ILLabel();

                context.Emit(OpCodes.Beq_S, lblContinue);
                context.Emit(OpCodes.Ret);

                context.MarkLabel(lblContinue);

                context.Emit(OpCodes.Pop);

                context.EmitLoadState(context.CurrBlock.Next);
            }
            else
            {
                context.EmitLdc_I8(op.Imm);

                context.Emit(OpCodes.Ret);
            }
        }
예제 #4
0
        private static void EmitPtPointerLoad(ILEmitterCtx context, ILLabel lblFallbackPath)
        {
            context.EmitLdc_I8(context.Memory.PageTable.ToInt64());

            context.Emit(OpCodes.Conv_I);

            int bit = MemoryManager.PageBits;

            do
            {
                context.EmitLdint(_tempIntAddress);

                if (context.CurrOp.RegisterSize == RegisterSize.Int32)
                {
                    context.Emit(OpCodes.Conv_U8);
                }

                context.EmitLsr(bit);

                bit += context.Memory.PtLevelBits;

                if (bit < context.Memory.AddressSpaceBits)
                {
                    context.EmitLdc_I8(context.Memory.PtLevelMask);

                    context.Emit(OpCodes.And);
                }

                context.EmitLdc_I8(IntPtr.Size);

                context.Emit(OpCodes.Mul);
                context.Emit(OpCodes.Conv_I);
                context.Emit(OpCodes.Add);
                context.Emit(OpCodes.Ldind_I);
            }while (bit < context.Memory.AddressSpaceBits);

            if (!context.Memory.HasWriteWatchSupport)
            {
                context.Emit(OpCodes.Conv_U8);

                context.EmitStint(_tempIntPtAddr);
                context.EmitLdint(_tempIntPtAddr);

                context.EmitLdc_I8(MemoryManager.PteFlagsMask);

                context.Emit(OpCodes.And);

                context.Emit(OpCodes.Brtrue, lblFallbackPath);

                context.EmitLdint(_tempIntPtAddr);

                context.Emit(OpCodes.Conv_I);
            }

            context.EmitLdint(_tempIntAddress);

            context.EmitLdc_I(MemoryManager.PageMask);

            context.Emit(OpCodes.And);
            context.Emit(OpCodes.Conv_I);
            context.Emit(OpCodes.Add);
        }