예제 #1
0
        public override bool Execute(ExecutionCore executionCore, uint opcode)
        {
            var condition = ArmConditionDecoder.Decode(opcode);

            var rn = (opcode & 0xF0000u) >> 16;
            var rnV = executionCore.R(rn).Value;

            var immediate = (opcode & 0x2000000u) != 0;
            var shift = (opcode & 0xF00u) >> 8;

            var op2 = 0u;
            var carry = false;

            if (immediate)
            {
                var nn = opcode & 0xFFu;
                var type = (opcode & 0x60u) >> 0x5;
                op2 = BitHelper.ShiftByType(nn, shift * 2, type);
                carry = BitHelper.CarryByType(nn, shift * 2, type);
            }
            else
                ;

            var temp = rnV ^ op2;
            executionCore.CurrentProgramStatusRegister.Zero = temp == 0;
            executionCore.CurrentProgramStatusRegister.Carry = carry;
            executionCore.CurrentProgramStatusRegister.Signed = (temp & 0x80000000u) != 0;

            return false;
        }
예제 #2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public static bool CheckCondition(ExecutionCore executionCore, ArmCondition condition)
        {
            var z = executionCore.CurrentProgramStatusRegister.Zero;
            var c = executionCore.CurrentProgramStatusRegister.Carry;
            var n = executionCore.CurrentProgramStatusRegister.Signed;
            var v = executionCore.CurrentProgramStatusRegister.Overflow;

            switch (condition)
            {
                case ArmCondition.Equals: return z;
                case ArmCondition.NotEquals: return !z;
                case ArmCondition.UnsignedHigherOrSame: return c;
                case ArmCondition.UnsignedLower: return !c;
                case ArmCondition.Negative: return n;
                case ArmCondition.Positive: return !n;
                case ArmCondition.Overflow: return v;
                case ArmCondition.NoOverflow: return !v;
                case ArmCondition.UnsignedHigher: return c && !z;
                case ArmCondition.UnsignedLowerOrSame: return !c || z;
                case ArmCondition.GreaterOrEqual: return n == v;
                case ArmCondition.LessThan: return n != v;
                case ArmCondition.GreaterThan: return !z && n == v;
                case ArmCondition.LessOrEqual: return z || n != v;
                case ArmCondition.Always: return true;
                case ArmCondition.Never: return false;
            }

            throw new NotSupportedException();
        }
예제 #3
0
        public override bool Execute(ExecutionCore executionCore, uint opcode)
        {
            var condition = ArmConditionDecoder.Decode(opcode);
            var pre = (opcode & 0x1000000u) != 0;
            var up = (opcode & 0x0800000u) != 0;
            var psr = (opcode & 0x0400000u) != 0;
            var write = (opcode & 0x0200000u) != 0;
            var load = (opcode & 0x0100000u) != 0;

            var rn = (opcode & 0xF0000u) >> 16;
            var registerList = (opcode & 0xFFFFu);

            var start = executionCore.R(rn).Value;

            for (var i = 15; i >= 0; --i)
            {
                if ((registerList & (1u << i)) != (1u << i))
                    continue;

                if (pre)
                {
                    start = start + (uint)(up ? 4 : -4);
                    executionCore.R(i).Value = executionCore.memoryManager.GetMemoryRegionForAddress(start).Read32(start);
                }
                else
                {
                    executionCore.R(i).Value = executionCore.memoryManager.GetMemoryRegionForAddress(start).Read32(start);
                    start = start + (uint)(up ? 4 : -4);
                }
            }

            return false;
        }
예제 #4
0
        public override bool Execute(ExecutionCore executionCore, uint opcode)
        {
            var condition = ArmConditionDecoder.Decode(opcode);
            var rn = (opcode & 0xF0000u) >> 16;
            var rd = (opcode & 0x0F000u) >> 12;
            var immediate = (opcode & 0x2000000u) != 0;
            var shift = (opcode & 0xF00u) >> 8;

            var op2 = 0u;
            var carry = false;

            if (immediate)
            {
                var nn = opcode & 0xFFu;
                var type = (opcode & 0x60u) >> 0x5;
                op2 = BitHelper.ShiftByType(nn, shift * 2, type);
                carry = BitHelper.CarryByType(nn, shift * 2, type);
            }
            else
                ;

            if (ArmConditionDecoder.CheckCondition(executionCore, condition))
            {
                executionCore.R(rd).Value = executionCore.R(rn).Value | op2;
                executionCore.CurrentProgramStatusRegister.Carry = carry;
            }

            return false;
        }
예제 #5
0
        public static uint RetrieveSecondOperand(ExecutionCore executionCore, uint opcode)
        {
            var registerAsSecondOperand = !HasImmediateOperand(opcode);

            if (registerAsSecondOperand)
            {
                var shiftByRegister = DoesShiftByRegister(opcode);

                if (shiftByRegister)
                {
                    var op2 = executionCore.R(OperandRegister(opcode)).Value;
                    var shiftAmount = executionCore.R(ImmediateShiftAmount(opcode)).Value;
                    return BitHelper.ShiftByType(op2, shiftAmount, ShiftType(opcode));
                }
                else
                {
                    var shiftAmount = ShiftAmount(opcode);
                    var op2 = executionCore.R(OperandRegister(opcode)).Value;
                    return BitHelper.ShiftByType(op2, shiftAmount, ShiftType(opcode));
                }
            }
            else
            {
                var shiftAmount = ImmediateShiftAmount(opcode);
                var immediate = OperandImmediate(opcode);

                return BitHelper.Ror(immediate, shiftAmount * 2);
            }
        }
예제 #6
0
        public override bool Execute(ExecutionCore executionCore, ushort opcode)
        {
            var rd = opcode & 0x7u;
            var rs = (opcode & 0x38u) >> 3;

            executionCore.R(rd).Value = executionCore.R(rd).Value & executionCore.R(rs).Value;
            return false;
        }
예제 #7
0
        public override bool Execute(ExecutionCore executionCore, ushort opcode)
        {
            // Move negated source register into destination register
            var rd = opcode & 0x7u;
            var rs = (opcode & 0x38u) >> 3;

            executionCore.R(rd).Value = ~executionCore.R(rs).Value;
            return false;
        }
예제 #8
0
        public override bool Execute(ExecutionCore executionCore, uint opcode)
        {
            var condition = ArmConditionDecoder.Decode(opcode);

            var cpsr = (opcode & 0x400000u) == 0;
            var reg = (cpsr ? executionCore.CurrentProgramStatusRegister as Register : executionCore.SavedProgramStatusRegister[executionCore.currentMode] as Register);
            var rd = (opcode & 0xF000u) >> 16;

            if (ArmConditionDecoder.CheckCondition(executionCore, condition))
                executionCore.R(rd).Value = reg.Value;

            return false;
        }
예제 #9
0
        public override bool Execute(ExecutionCore executionCore, ushort opcode)
        {
            var rs = (opcode & 0x38) >> 0x3;
            var rd = opcode & 0x7;

            var carry = executionCore.CurrentProgramStatusRegister.Carry ? 0 : 1;

            var rsV = executionCore.R(rs).Value;
            var rdV = executionCore.R(rd).Value;

            executionCore.R(rd).Value = (uint)(rdV - rsV - carry);

            return false;
        }
예제 #10
0
        public override bool Execute(ExecutionCore executionCore, ushort opcode)
        {
            var offset = ((opcode & 0x7C0u) >> 6) & 0xFFu;
            var rd = opcode & 0x7u;
            var rs = (opcode & 0x38u) >> 3;

            if ((opcode & 0x4000u) == 0x4000u)
            {
                offset = executionCore.R(rs).Value & 0xFFu;
                rs = rd;
            }

            executionCore.R(rd).Value = executionCore.R(rs).Value >> (int)offset;
            return false;
        }
예제 #11
0
        public override bool Execute(ExecutionCore executionCore, uint opcode)
        {
            var condition = ArmConditionDecoder.Decode(opcode);
            var rn = (opcode & 0xF0000u) >> 16;
            var rd = (opcode & 0x0F000u) >> 12;

            if (ArmConditionDecoder.CheckCondition(executionCore, condition))
            {
                var offset = (uint)(opcode & 0xFFFu);
                var address = (uint)(executionCore.R(rn).Value + offset);

                if (rn == 15)
                    address = address + 8;
                executionCore.R(rd).Value = executionCore.memoryManager.GetMemoryForAddress(address).GetMemoryRegionForAddress(address).Read32(address);
            }

            return false;
        }
예제 #12
0
        public override bool Execute(ExecutionCore executionCore, ushort opcode)
        {
            var rd = opcode & 0x7u;
            var rb = (opcode & 0x38u) >> 3;
            var offset = (opcode & 0x7C0u) >> 6;

            if ((opcode & 0x4800u) == 0x4800u)
            {
                rd = (opcode & 0x700u) >> 8;
                rb = 15;
                offset = opcode & 0xFFu;
                offset = offset * 4;
            }

            var address = rb == 15 ? ((executionCore.PC.Value + 4) & ~2u) + offset : executionCore.R(rb).Value + offset;

            executionCore.R(rd).Value = executionCore.memoryManager.GetMemoryRegionForAddress(address).Read32(address);

            return false;
        }
예제 #13
0
        public override bool Execute(ExecutionCore executionCore, uint opcode)
        {
            var condition = ArmConditionDecoder.Decode(opcode);

            var rn = DataProcessing.RnOperandValue(executionCore, opcode);
            var op2 = DataProcessing.RetrieveSecondOperand(executionCore, opcode);

            if (!ArmConditionDecoder.CheckCondition(executionCore, condition))
                return false;

            var temp = (uint)(rn & op2);

            if (DataProcessing.SetsConditionCodes(opcode))
            {
                var carry = DataProcessing.DoesCreateCarry(opcode);
                executionCore.CurrentProgramStatusRegister.Carry = carry;
                executionCore.CurrentProgramStatusRegister.Zero = temp == 0;
                executionCore.CurrentProgramStatusRegister.Signed = (temp & 0x80000000u) != 0;
            }

            return false;
        }
예제 #14
0
 public override bool Execute(ExecutionCore executionCore, uint opcode)
 {
     return false;
 }
예제 #15
0
 public static uint RnOperandValue(ExecutionCore executionCore, uint opcode)
 {
     if (RnOperand(opcode) < 0xFu)
         return executionCore.R(RnOperand(opcode)).Value;
     if (!HasImmediateOperand(opcode) && DoesShiftByRegister(opcode))
         return executionCore.R(RnOperand(opcode)).Value + 12;
     else
         return executionCore.R(RnOperand(opcode)).Value + 8;
 }