예제 #1
0
        private static void EmitLoadAddress(ILEmitterCtx context)
        {
            switch (context.CurrOp)
            {
            case OpCodeMemImm64 op:
                context.EmitLdint(op.Rn);

                if (!op.PostIdx)
                {
                    // Pre-indexing.
                    context.EmitLdc_I(op.Imm);

                    context.Emit(OpCodes.Add);
                }
                break;

            case OpCodeMemReg64 op:
                context.EmitLdint(op.Rn);
                context.EmitLdintzr(op.Rm);
                context.EmitCast(op.IntType);

                if (op.Shift)
                {
                    context.EmitLsl(op.Size);
                }

                context.Emit(OpCodes.Add);
                break;
            }

            // Save address to Scratch var since the register value may change.
            context.Emit(OpCodes.Dup);

            context.EmitSttmp();
        }
예제 #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();
            }
        }