예제 #1
0
        private static void EmitBranch(ILEmitterCtx context, OpCode ilOp)
        {
            OpCodeBImm64 op = (OpCodeBImm64)context.CurrOp;

            if (context.CurrBlock.Branch != null)
            {
                context.Emit(ilOp, context.GetLabel(op.Imm));

                if (context.CurrBlock.Next == null)
                {
                    context.EmitStoreContext();
                    context.EmitLdc_I8(op.Position + 4);

                    context.Emit(OpCodes.Ret);
                }
            }
            else
            {
                context.EmitStoreContext();

                ILLabel lblTaken = new ILLabel();

                context.Emit(ilOp, lblTaken);

                context.EmitLdc_I8(op.Position + 4);

                context.Emit(OpCodes.Ret);

                context.MarkLabel(lblTaken);

                context.EmitLdc_I8(op.Imm);

                context.Emit(OpCodes.Ret);
            }
        }
예제 #2
0
        public static void Ret(ILEmitterCtx context)
        {
            context.EmitStoreContext();
            context.EmitLdint(RegisterAlias.Lr);

            context.Emit(OpCodes.Ret);
        }
예제 #3
0
        public static void Bx(ILEmitterCtx context)
        {
            IOpCode32BReg op = (IOpCode32BReg)context.CurrOp;

            context.EmitStoreContext();

            EmitLoadFromRegister(context, op.Rm);

            EmitBxWritePc(context);
        }
예제 #4
0
        public static void EmitCall(ILEmitterCtx context, long imm)
        {
            if (context.Tier == TranslationTier.Tier0)
            {
                context.EmitStoreContext();

                context.TranslateAhead(imm);

                context.EmitLdc_I8(imm);

                context.Emit(OpCodes.Ret);

                return;
            }

            if (!context.TryOptEmitSubroutineCall())
            {
                context.HasSlowCall = true;

                context.EmitStoreContext();

                context.TranslateAhead(imm);

                context.EmitLdarg(TranslatedSub.StateArgIdx);

                context.EmitLdfld(typeof(CpuThreadState).GetField(nameof(CpuThreadState.CurrentTranslator),
                                                                  BindingFlags.Instance |
                                                                  BindingFlags.NonPublic));

                context.EmitLdarg(TranslatedSub.StateArgIdx);
                context.EmitLdc_I8(imm);
                context.EmitLdc_I4((int)CallType.Call);

                context.EmitPrivateCall(typeof(Translator), nameof(Translator.GetOrTranslateSubroutine));

                context.EmitLdarg(TranslatedSub.StateArgIdx);
                context.EmitLdarg(TranslatedSub.MemoryArgIdx);

                context.EmitCall(typeof(TranslatedSub), nameof(TranslatedSub.Execute));
            }

            EmitContinueOrReturnCheck(context);
        }
예제 #5
0
        public static void Br(ILEmitterCtx context)
        {
            OpCodeBReg64 op = (OpCodeBReg64)context.CurrOp;

            context.HasIndirectJump = true;

            context.EmitStoreContext();
            context.EmitLdintzr(op.Rn);

            EmitVirtualJump(context);
        }
예제 #6
0
        public static void Blr(ILEmitterCtx context)
        {
            OpCodeBReg64 op = (OpCodeBReg64)context.CurrOp;

            context.EmitLdintzr(op.Rn);
            context.EmitLdc_I(op.Position + 4);
            context.EmitStint(RegisterAlias.Lr);
            context.EmitStoreContext();

            EmitVirtualCall(context);
        }
예제 #7
0
        public static void EmitStoreToRegister(ILEmitterCtx context, int register)
        {
            if (register == RegisterAlias.Aarch32Pc)
            {
                context.EmitStoreContext();

                EmitBxWritePc(context);
            }
            else
            {
                context.EmitStint(GetRegisterAlias(context.Mode, register));
            }
        }
예제 #8
0
        public static void B(ILEmitterCtx context)
        {
            IOpCode32BImm op = (IOpCode32BImm)context.CurrOp;

            if (context.CurrBlock.Branch != null)
            {
                context.Emit(OpCodes.Br, context.GetLabel(op.Imm));
            }
            else
            {
                context.EmitStoreContext();
                context.EmitLdc_I8(op.Imm);

                context.Emit(OpCodes.Ret);
            }
        }
예제 #9
0
        private static void EmitAluWritePc(ILEmitterCtx context)
        {
            context.EmitStoreContext();

            if (IsThumb(context.CurrOp))
            {
                context.EmitLdc_I4(~1);

                context.Emit(OpCodes.And);
                context.Emit(OpCodes.Conv_U8);
                context.Emit(OpCodes.Ret);
            }
            else
            {
                EmitBxWritePc(context);
            }
        }
예제 #10
0
        private static void EmitExceptionCall(ILEmitterCtx context, string mthdName)
        {
            OpCodeException64 op = (OpCodeException64)context.CurrOp;

            context.EmitStoreContext();

            context.EmitLdarg(TranslatedSub.StateArgIdx);

            context.EmitLdc_I8(op.Position);
            context.EmitLdc_I4(op.Id);

            context.EmitPrivateCall(typeof(CpuThreadState), mthdName);

            //Check if the thread should still be running, if it isn't then we return 0
            //to force a return to the dispatcher and then exit the thread.
            context.EmitLdarg(TranslatedSub.StateArgIdx);

            context.EmitCallPropGet(typeof(CpuThreadState), nameof(CpuThreadState.Running));

            ILLabel lblEnd = new ILLabel();

            context.Emit(OpCodes.Brtrue_S, lblEnd);

            context.EmitLdc_I8(0);

            context.Emit(OpCodes.Ret);

            context.MarkLabel(lblEnd);

            if (context.CurrBlock.Next != null)
            {
                context.EmitLoadContext();
            }
            else
            {
                context.EmitLdc_I8(op.Position + 4);

                context.Emit(OpCodes.Ret);
            }
        }
예제 #11
0
        public static void Und(ILEmitterCtx context)
        {
            OpCode64 op = context.CurrOp;

            context.EmitStoreContext();

            context.EmitLdarg(TranslatedSub.StateArgIdx);

            context.EmitLdc_I8(op.Position);
            context.EmitLdc_I4(op.RawOpCode);

            context.EmitPrivateCall(typeof(CpuThreadState), nameof(CpuThreadState.OnUndefined));

            if (context.CurrBlock.Next != null)
            {
                context.EmitLoadContext();
            }
            else
            {
                context.EmitLdc_I8(op.Position + 4);

                context.Emit(OpCodes.Ret);
            }
        }