예제 #1
0
        private static void EmitAsrC(ILEmitterCtx context, bool setCarry, int shift)
        {
            if ((uint)shift >= 32)
            {
                context.EmitAsr(31);

                if (setCarry)
                {
                    context.Emit(OpCodes.Dup);

                    context.EmitLdc_I4(1);

                    context.Emit(OpCodes.And);

                    context.EmitStflg((int)PState.CBit);
                }
            }
            else
            {
                if (setCarry)
                {
                    context.Emit(OpCodes.Dup);

                    context.EmitLsr(shift - 1);

                    context.EmitLdc_I4(1);

                    context.Emit(OpCodes.And);

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

                context.EmitAsr(shift);
            }
        }
예제 #2
0
        public static void EmitDataLoadOper2(ILEmitterCtx context)
        {
            switch (context.CurrOp)
            {
            case IOpCodeAluImm64 op:
                context.EmitLdc_I(op.Imm);
                break;

            case IOpCodeAluRs64 op:
                context.EmitLdintzr(op.Rm);

                switch (op.ShiftType)
                {
                case ShiftType.Lsl: context.EmitLsl(op.Shift); break;

                case ShiftType.Lsr: context.EmitLsr(op.Shift); break;

                case ShiftType.Asr: context.EmitAsr(op.Shift); break;

                case ShiftType.Ror: context.EmitRor(op.Shift); break;
                }
                break;

            case IOpCodeAluRx64 op:
                context.EmitLdintzr(op.Rm);
                context.EmitCast(op.IntType);
                context.EmitLsl(op.Shift);
                break;
            }
        }
예제 #3
0
        public static void EmitAluLoadOper2(ILEmitterCtx context, bool setCarry = true)
        {
            switch (context.CurrOp)
            {
            // ARM32.
            case OpCode32AluImm op:
                context.EmitLdc_I4(op.Imm);

                if (op.SetFlags && op.IsRotated)
                {
                    context.EmitLdc_I4((int)((uint)op.Imm >> 31));

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

            case OpCode32AluRsImm op:
                EmitLoadRmShiftedByImmediate(context, op, setCarry);
                break;

            case OpCodeT16AluImm8 op:
                context.EmitLdc_I4(op.Imm);
                break;

            // ARM64.
            case IOpCodeAluImm64 op:
                context.EmitLdc_I(op.Imm);
                break;

            case IOpCodeAluRs64 op:
                context.EmitLdintzr(op.Rm);

                switch (op.ShiftType)
                {
                case ShiftType.Lsl: context.EmitLsl(op.Shift); break;

                case ShiftType.Lsr: context.EmitLsr(op.Shift); break;

                case ShiftType.Asr: context.EmitAsr(op.Shift); break;

                case ShiftType.Ror: context.EmitRor(op.Shift); break;
                }
                break;

            case IOpCodeAluRx64 op:
                context.EmitLdintzr(op.Rm);
                context.EmitCast(op.IntType);
                context.EmitLsl(op.Shift);
                break;

            default: throw new InvalidOperationException();
            }
        }
예제 #4
0
        public static void Sbfm(ILEmitterCtx context)
        {
            OpCodeBfm64 op = (OpCodeBfm64)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
            {
                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);
            }
        }
예제 #5
0
        private static void EmitBfiz(ILEmitterCtx context, bool signed)
        {
            OpCodeBfm64 op = (OpCodeBfm64)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);
        }