예제 #1
0
        public static void Fcsel_S(ArmEmitterContext context)
        {
            OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp;

            Operand lblTrue = Label();
            Operand lblEnd  = Label();

            Operand isTrue = InstEmitFlowHelper.GetCondTrue(context, op.Cond);

            context.BranchIfTrue(lblTrue, isTrue);

            OperandType type = op.Size == 0 ? OperandType.FP32 : OperandType.FP64;

            Operand me = context.VectorExtract(type, GetVec(op.Rm), 0);

            context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), me, 0));

            context.Branch(lblEnd);

            context.MarkLabel(lblTrue);

            Operand ne = context.VectorExtract(type, GetVec(op.Rn), 0);

            context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), ne, 0));

            context.MarkLabel(lblEnd);
        }
예제 #2
0
        public static void EmitBxWritePc(ArmEmitterContext context, Operand pc, int sourceRegister = 0)
        {
            bool    isReturn = sourceRegister == RegisterAlias.Aarch32Lr || IsA32Return(context);
            Operand mode     = context.BitwiseAnd(pc, Const(1));

            SetFlag(context, PState.TFlag, mode);

            Operand addr = context.ConditionalSelect(mode, context.BitwiseAnd(pc, Const(~1)), context.BitwiseAnd(pc, Const(~3)));

            InstEmitFlowHelper.EmitVirtualJump(context, addr, isReturn);
        }
예제 #3
0
        private static void EmitAluWritePc(ArmEmitterContext context, Operand value)
        {
            Debug.Assert(value.Type == OperandType.I32);

            if (IsThumb(context.CurrOp))
            {
                context.StoreToContext();
                bool isReturn = IsA32Return(context);

                Operand addr = context.BitwiseOr(value, Const(1));

                InstEmitFlowHelper.EmitVirtualJump(context, addr, isReturn);
            }
            else
            {
                EmitBxWritePc(context, value);
            }
        }
예제 #4
0
        private static void EmitAluWritePc(ArmEmitterContext context, Operand value)
        {
            Debug.Assert(value.Type == OperandType.I32);

            if (((OpCode32)context.CurrOp).IsThumb())
            {
                bool isReturn = IsA32Return(context);
                if (!isReturn)
                {
                    context.StoreToContext();
                }

                InstEmitFlowHelper.EmitVirtualJump(context, value, isReturn);
            }
            else
            {
                EmitBxWritePc(context, value);
            }
        }
예제 #5
0
        private static void EmitFccmpOrFccmpe(ArmEmitterContext context, bool signalNaNs)
        {
            OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp;

            Operand lblTrue = Label();
            Operand lblEnd  = Label();

            context.BranchIfTrue(lblTrue, InstEmitFlowHelper.GetCondTrue(context, op.Cond));

            EmitSetNzcv(context, op.Nzcv);

            context.Branch(lblEnd);

            context.MarkLabel(lblTrue);

            EmitFcmpOrFcmpe(context, signalNaNs);

            context.MarkLabel(lblEnd);
        }
예제 #6
0
        private static void Blx(ArmEmitterContext context, bool x)
        {
            IOpCode32BImm op = (IOpCode32BImm)context.CurrOp;

            uint pc = op.GetPc();

            bool isThumb = IsThumb(context.CurrOp);

            uint currentPc = isThumb
                ? op.GetPc() | 1
                : op.GetPc() - 4;

            SetIntOrSP(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc));

            // If x is true, then this is a branch with link and exchange.
            // In this case we need to swap the mode between Arm <-> Thumb.
            if (x)
            {
                SetFlag(context, PState.TFlag, Const(isThumb ? 0 : 1));
            }

            InstEmitFlowHelper.EmitCall(context, (ulong)op.Immediate);
        }