Beispiel #1
0
        private static void EmitDoublingMultiplyHighHalf(AILEmitterCtx Context, bool Round)
        {
            AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;

            int ESize = 8 << Op.Size;

            Context.Emit(OpCodes.Mul);

            if (!Round)
            {
                Context.EmitAsr(ESize - 1);
            }
            else
            {
                long RoundConst = 1L << (ESize - 1);

                AILLabel LblTrue = new AILLabel();

                Context.EmitLsl(1);

                Context.EmitLdc_I8(RoundConst);

                Context.Emit(OpCodes.Add);

                Context.EmitAsr(ESize);

                Context.Emit(OpCodes.Dup);
                Context.EmitLdc_I8((long)int.MinValue);
                Context.Emit(OpCodes.Bne_Un_S, LblTrue);

                Context.Emit(OpCodes.Neg);

                Context.MarkLabel(LblTrue);
            }
        }
Beispiel #2
0
        public static void Sbfm(AILEmitterCtx Context)
        {
            AOpCodeBfm Op = (AOpCodeBfm)Context.CurrOp;

            int BitsCount = Op.GetBitsCount();

            if (Op.Pos + 1 == BitsCount)
            {
                EmitSbfmShift(Context);
            }
            else if (Op.Pos < Op.Shift)
            {
                EmitSbfiz(Context);
            }
            else if (Op.Pos == 7 && Op.Shift == 0)
            {
                EmitSbfmCast(Context, OpCodes.Conv_I1);
            }
            else if (Op.Pos == 15 && Op.Shift == 0)
            {
                EmitSbfmCast(Context, OpCodes.Conv_I2);
            }
            else if (Op.Pos == 31 && Op.Shift == 0)
            {
                EmitSbfmCast(Context, OpCodes.Conv_I4);
            }
            else if (Op.Shift == 0)
            {
                Context.EmitLdintzr(Op.Rn);

                Context.EmitLsl(BitsCount - 1 - Op.Pos);
                Context.EmitAsr(BitsCount - 1);

                Context.EmitStintzr(Op.Rd);
            }
            else
            {
                EmitBfmLoadRn(Context);

                Context.EmitLdintzr(Op.Rn);

                Context.EmitLsl(BitsCount - 1 - Op.Pos);
                Context.EmitAsr(BitsCount - 1);

                Context.EmitLdc_I(~Op.TMask);

                Context.Emit(OpCodes.And);
                Context.Emit(OpCodes.Or);

                Context.EmitStintzr(Op.Rd);
            }
        }
        public static void EmitDataLoadOper2(AILEmitterCtx Context)
        {
            switch (Context.CurrOp)
            {
            case IAOpCodeAluImm Op:
                Context.EmitLdc_I(Op.Imm);
                break;

            case IAOpCodeAluRs Op:
                Context.EmitLdintzr(Op.Rm);

                switch (Op.ShiftType)
                {
                case AShiftType.Lsl: Context.EmitLsl(Op.Shift); break;

                case AShiftType.Lsr: Context.EmitLsr(Op.Shift); break;

                case AShiftType.Asr: Context.EmitAsr(Op.Shift); break;

                case AShiftType.Ror: Context.EmitRor(Op.Shift); break;
                }
                break;

            case IAOpCodeAluRx Op:
                Context.EmitLdintzr(Op.Rm);
                Context.EmitCast(Op.IntType);
                Context.EmitLsl(Op.Shift);
                break;
            }
        }
Beispiel #4
0
        private static void EmitBfiz(AILEmitterCtx Context, bool Signed)
        {
            AOpCodeBfm Op = (AOpCodeBfm)Context.CurrOp;

            int Width = Op.Pos + 1;

            Context.EmitLdintzr(Op.Rn);

            Context.EmitLsl(Op.GetBitsCount() - Width);

            if (Signed)
            {
                Context.EmitAsr(Op.Shift - Width);
            }
            else
            {
                Context.EmitLsr(Op.Shift - Width);
            }

            Context.EmitStintzr(Op.Rd);
        }