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

            if (context.CurrBlock.Next != null &&
                context.CurrBlock.Branch != null)
            {
                context.EmitCondBranch(context.GetLabel(op.Imm), cond);
            }
            else
            {
                context.EmitStoreState();

                ILLabel lblTaken = new ILLabel();

                context.EmitCondBranch(lblTaken, cond);

                context.EmitLdc_I8(op.Position + 4);

                context.Emit(OpCodes.Ret);

                context.MarkLabel(lblTaken);

                context.EmitLdc_I8(op.Imm);

                context.Emit(OpCodes.Ret);
            }
        }
예제 #2
0
        private static void EmitCsel(ILEmitterCtx context, CselOperation cselOp)
        {
            OpCodeCsel64 op = (OpCodeCsel64)context.CurrOp;

            ILLabel lblTrue = new ILLabel();
            ILLabel lblEnd  = new ILLabel();

            context.EmitCondBranch(lblTrue, op.Cond);
            context.EmitLdintzr(op.Rm);

            if (cselOp == CselOperation.Increment)
            {
                context.EmitLdc_I(1);

                context.Emit(OpCodes.Add);
            }
            else if (cselOp == CselOperation.Invert)
            {
                context.Emit(OpCodes.Not);
            }
            else if (cselOp == CselOperation.Negate)
            {
                context.Emit(OpCodes.Neg);
            }

            context.Emit(OpCodes.Br_S, lblEnd);

            context.MarkLabel(lblTrue);

            context.EmitLdintzr(op.Rn);

            context.MarkLabel(lblEnd);

            context.EmitStintzr(op.Rd);
        }
예제 #3
0
        private static void EmitCcmp(ILEmitterCtx context, CcmpOp cmpOp)
        {
            OpCodeCcmp64 op = (OpCodeCcmp64)context.CurrOp;

            ILLabel lblTrue = new ILLabel();
            ILLabel lblEnd  = new ILLabel();

            context.EmitCondBranch(lblTrue, op.Cond);

            context.EmitLdc_I4((op.Nzcv >> 0) & 1);

            context.EmitStflg((int)PState.VBit);

            context.EmitLdc_I4((op.Nzcv >> 1) & 1);

            context.EmitStflg((int)PState.CBit);

            context.EmitLdc_I4((op.Nzcv >> 2) & 1);

            context.EmitStflg((int)PState.ZBit);

            context.EmitLdc_I4((op.Nzcv >> 3) & 1);

            context.EmitStflg((int)PState.NBit);

            context.Emit(OpCodes.Br_S, lblEnd);

            context.MarkLabel(lblTrue);

            EmitAluLoadOpers(context);

            if (cmpOp == CcmpOp.Cmp)
            {
                context.Emit(OpCodes.Sub);

                context.EmitZnFlagCheck();

                EmitSubsCCheck(context);
                EmitSubsVCheck(context);
            }
            else if (cmpOp == CcmpOp.Cmn)
            {
                context.Emit(OpCodes.Add);

                context.EmitZnFlagCheck();

                EmitAddsCCheck(context);
                EmitAddsVCheck(context);
            }
            else
            {
                throw new ArgumentException(nameof(cmpOp));
            }

            context.Emit(OpCodes.Pop);

            context.MarkLabel(lblEnd);
        }
예제 #4
0
        public static void Fccmp_S(ILEmitterCtx context)
        {
            OpCodeSimdFcond64 op = (OpCodeSimdFcond64)context.CurrOp;

            ILLabel lblTrue = new ILLabel();
            ILLabel lblEnd  = new ILLabel();

            context.EmitCondBranch(lblTrue, op.Cond);

            EmitSetNzcv(context, op.Nzcv);

            context.Emit(OpCodes.Br, lblEnd);

            context.MarkLabel(lblTrue);

            Fcmp_S(context);

            context.MarkLabel(lblEnd);
        }
예제 #5
0
        public static void Fcsel_S(ILEmitterCtx context)
        {
            OpCodeSimdFcond64 op = (OpCodeSimdFcond64)context.CurrOp;

            ILLabel lblTrue = new ILLabel();
            ILLabel lblEnd  = new ILLabel();

            context.EmitCondBranch(lblTrue, op.Cond);

            EmitVectorExtractF(context, op.Rm, 0, op.Size);

            context.Emit(OpCodes.Br_S, lblEnd);

            context.MarkLabel(lblTrue);

            EmitVectorExtractF(context, op.Rn, 0, op.Size);

            context.MarkLabel(lblEnd);

            EmitScalarSetF(context, op.Rd, op.Size);
        }