コード例 #1
0
        protected override void ExecuteInternal(Aarch32CpuState cpuState, uint operand2Value)
        {
            var rn  = cpuState.Registers[Rn];
            var res = rn - operand2Value;

            SetFlagsArithmethic(cpuState, res, rn, operand2Value, false, true);
        }
コード例 #2
0
        protected override void ExecuteInternal(Aarch32CpuState cpuState, uint operand2Value)
        {
            var rn  = cpuState.Registers[Rn];
            var res = rn ^ operand2Value;

            SetFlagsLogical(cpuState, res);
        }
コード例 #3
0
        protected void SetFlagsLogical(Aarch32CpuState cpuState, uint result)
        {
            var z = result == 0;
            var n = result >> 31 == 1;

            cpuState.Z = z;
            cpuState.N = n;
        }
コード例 #4
0
 protected override void ExecuteInternal(Aarch32CpuState cpuState, uint operand2Value)
 {
     cpuState.Registers[Rd] = ~operand2Value;
     if (S)
     {
         SetFlagsLogical(cpuState, ~operand2Value);
     }
 }
コード例 #5
0
        protected override void ExecuteInternal(Aarch32CpuState cpuState, uint operand2Value)
        {
            var rn         = cpuState.Registers[Rn];
            var rdNewValue = rn & ~operand2Value;

            cpuState.Registers[Rd] = rdNewValue;
            if (S)
            {
                SetFlagsLogical(cpuState, rdNewValue);
            }
        }
コード例 #6
0
        protected override void ExecuteInternal(Aarch32CpuState cpuState, uint operand2Value)
        {
            var rn         = cpuState.Registers[Rn];
            var rdNewValue = operand2Value - rn;

            cpuState.Registers[Rd] = rdNewValue;
            if (S)
            {
                SetFlagsArithmethic(cpuState, rdNewValue, operand2Value, rn, false, true);
            }
        }
コード例 #7
0
        protected void SetFlagsArithmethic(Aarch32CpuState cpuState, uint result, uint value, uint value2, bool add, bool carryIn)
        {
            SetFlagsLogical(cpuState, result);

            var c = !carryIn ? result < value : result <= value;
            var v = !add ?
                    value >> 31 != value2 >> 31 && value >> 31 != result >> 31 :
                    value >> 31 == value2 >> 31 && value >> 31 != result >> 31;

            cpuState.C = c;
            cpuState.V = v;
        }
コード例 #8
0
        protected override void ExecuteInternal(Aarch32CpuState cpuState, uint operand2Value)
        {
            var rn         = cpuState.Registers[Rn];
            var rdNewValue = rn - operand2Value;
            var c          = cpuState.C;

            rdNewValue -= (uint)(c ? 0 : 1);

            cpuState.Registers[Rd] = rdNewValue;
            if (S)
            {
                SetFlagsArithmethic(cpuState, rdNewValue, rn, operand2Value, false, c);
            }
        }
コード例 #9
0
        protected uint GetOp2Value(Aarch32CpuState state, bool isDisassemble = false)
        {
            uint shifted;
            bool carry;

            if (I)
            {
                var imm = Operand2 & 0xFF;
                var rot = ((Operand2 >> 8) & 0xF) * 2;

                shifted = BarrelShifter.Instance.Ror(imm, (int)rot, out carry);
                if (rot == 0 && !isDisassemble)
                {
                    carry = state.C;
                }
            }
            else
            {
                var rm    = Operand2 & 0xF;
                var shift = (Operand2 >> 4) & 0xFF;

                var stype      = (shift >> 1) & 0x3;
                var shiftValue = (shift & 0x1) == 1 ?
                                 state.Registers[(shift >> 4) & 0xF] & 0xFF :
                                 shift >> 3;
                if ((shift & 0x1) == 0 && (stype == 1 || stype == 2) && shiftValue == 0)
                {
                    shiftValue = 32;
                }

                shifted = BarrelShifter.Instance.ShiftByType((ShiftType)stype, state.Registers[rm], (int)shiftValue, out carry);
                if (shiftValue == 0 && !isDisassemble)
                {
                    carry = state.C;
                }
            }

            if (S && IsLogical && !isDisassemble)
            {
                state.C = carry;
            }

            return(shifted);
        }
コード例 #10
0
        private uint ShiftValue(Aarch32CpuState cpuState)
        {
            var rm    = _offset & 0xF;
            var shift = (_offset >> 4) & 0xFF;

            var shiftType  = (shift >> 1) & 0x3;
            var shiftValue = shift >> 3;

            if ((shift & 0x1) == 0 && (shiftType == 1 || shiftType == 2) && shiftValue == 0)
            {
                shiftValue = 32;
            }

            var newOffset = BarrelShifter.Instance.ShiftByType((ShiftType)shiftType, cpuState.Registers[rm], (int)shiftValue, out var carry);

            cpuState.C = carry;

            return(newOffset);
        }
コード例 #11
0
 protected abstract void ExecuteInternal(Aarch32CpuState cpuState, uint operand2Value);
コード例 #12
0
        public static bool CanExecute(Aarch32CpuState state, byte condition)
        {
            if (condition > 14)
            {
                throw new UnknownConditionException(condition);
            }

            var(z, c, n, v) = (state.Z, state.C, state.N, state.V);

            switch (condition)
            {
            case 0:
                return(z);

            case 1:
                return(!z);

            case 2:
                return(c);

            case 3:
                return(!c);

            case 4:
                return(n);

            case 5:
                return(!n);

            case 6:
                return(v);

            case 7:
                return(!v);

            case 8:
                return(c && !z);

            case 9:
                return(!c || z);

            case 10:
                return(n == v);

            case 11:
                return(n != v);

            case 12:
                return(!z && n == v);

            case 13:
                return(z || n != v);

            case 14:
                return(true);

            default:
                // Path gets never reached, due to initial if statement
                return(false);
            }
        }