Exemple #1
0
        }        //calculateMultM

        //32bit multiply instructions (MUL/MLA)
        internal uint ExecuteDataOpMultiply(DataOpMultiplyRaw opHandler, uint opcode, bool setflags)
        {
            //The original code used the masks rd_mask, rn_mask, rm_mask and rs_mask here
            //But the operands are in a strange order so the masks were used in a confusing way.
            //Therefore, we have one of the rare cases where it's better to use magic numbers...
            uint Rm = (opcode) & 0xf;
            uint Rs = (opcode >> 8) & 0xf;
            uint Rd = (opcode >> 16) & 0xf;
            uint Rn = (opcode >> 12) & 0xf;

            uint rs_value = get_reg(Rs);
            uint rm_value = get_reg(Rm);
            uint rn_value = get_reg(Rn);
            //The number of cycles taken for multiplication varies depending
            //on the magnitude of rs_value.
            uint M = calculateMultM(rs_value);

            MultiplyOpResult result = opHandler(rn_value, rs_value, rm_value);

            mGPR[Rd] = result.output_value;

            if (setflags)
            {
                CPSR.set_NZCV((result.output_value & 0x80000000) != 0, result.output_value == 0, CPSR.cf, CPSR.vf);
            }

            return(M + result.cycles);
        }
Exemple #2
0
        //64bit multiply instructions (SMULL/UMULL/SMLAL/UMLAL)
        internal uint ExecuteDataOpMultiplyLong(DataOpMultiplyLongRaw opHandler, uint opcode, bool setflags)
        {
            //See comment in ExecuteDataOpMultiply
            uint Rm   = (opcode) & 0xf;
            uint Rs   = (opcode >> 8) & 0xf;
            uint RdHi = (opcode >> 16) & 0xf;
            uint RdLo = (opcode >> 12) & 0xf;

            uint   rs_value     = get_reg(Rs);
            uint   rm_value     = get_reg(Rm);
            UInt64 rdhilo_value = (((UInt64)get_reg(RdHi)) << 32) | (UInt64)get_reg(RdLo);
            //The number of cycles taken for multiplication varies depending
            //on the magnitude of rs_value.
            uint M = calculateMultM(rs_value);


            LongMultiplyOpResult result = opHandler(rdhilo_value, rs_value, rm_value);

            mGPR[RdHi] = (UInt32)((result.output_value >> 32) & 0xffffffff);
            mGPR[RdLo] = (UInt32)((result.output_value) & 0xffffffff);
            //If we set the flags after a long multiply, the N flag is based on bit 63, not bit 31.
            if (setflags)
            {
                CPSR.set_NZCV((result.output_value & 0x8000000000000000) != 0, result.output_value == 0, CPSR.cf, CPSR.vf);
            }

            return(result.cycles + M);
        }
Exemple #3
0
        protected BaseARMCore()
        {
            this.TrapUnalignedMemoryAccess = true;

            mCPSR = new CPSR();
            mGPR  = new GeneralPurposeRegisters(mCPSR);
            mFPP  = new FloatingPointProcessor(this);
            this.Reset();
        }//Jimulator ctor
Exemple #4
0
 internal void DataOpHandleSetFlagsAWC_NonCMP(uint opcode, uint Rd, AWCResult awcResult)
 {
     if (Rd == GeneralPurposeRegisters.PCRegisterIndex)
     {
         CPSR.RestoreCPUMode();
     }
     else
     {
         DataOpHandleSetFlagsAWC_CMP(opcode, Rd, awcResult);
     }
 }
Exemple #5
0
 internal void DataOpHandleSetFlagsLogical_NonCMP(uint opcode, uint Rd, uint result, bool shift_carry)
 {
     if (Rd == GeneralPurposeRegisters.PCRegisterIndex)
     {
         CPSR.RestoreCPUMode();
     }
     else
     {
         DataOpHandleSetFlagsLogical_CMP(opcode, Rd, result, shift_carry);
     }
 }
Exemple #6
0
        }//ExecuteARMInstruction

        /// <summary>
        /// Check the condition code(cc) of the current instruction and determine if
        /// the instruction should be executed or not.
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        internal bool check_cc(byte condition)
        {
            CPSR cpsr = this.CPSR;

            switch (condition & 0x0f)
            {
            case 0x00: return(cpsr.zf);

            case 0x01: return(!cpsr.zf);

            case 0x02: return(cpsr.cf);

            case 0x03: return(!cpsr.cf);

            case 0x04: return(cpsr.nf);

            case 0x05: return(!cpsr.nf);

            case 0x06: return(cpsr.vf);

            case 0x07: return(!cpsr.vf);

            //case 0X8: go = and(cf(cpsr), not(zf(cpsr)));                     break;
            case 0x08: return(cpsr.cf && !cpsr.zf);

            //case 0X9: go = or(not(cf(cpsr)), zf(cpsr));                      break;
            case 0x09: return(!cpsr.cf || cpsr.zf);

            //case 0XA: go = not(xor(nf(cpsr), vf(cpsr)));                     break;
            case 0x0a: return(!(cpsr.nf ^ cpsr.vf));

            //case 0XB: go = xor(nf(cpsr), vf(cpsr));                          break;
            case 0x0b: return(cpsr.nf ^ cpsr.vf);

            //case 0XC: go = and(not(zf(cpsr)), not(xor(nf(cpsr), vf(cpsr)))); break;
            case 0x0c: return(!cpsr.zf && (!(cpsr.nf ^ cpsr.vf)));

            //case 0XD: go = or(zf(cpsr), xor(nf(cpsr), vf(cpsr)));            break;
            case 0xd: return(cpsr.zf || (cpsr.nf ^ cpsr.vf));

            case 0x0e: return(true);

            case 0x0f: return(false);

            default: return(false);
            } //switch
        }     //check_cc
Exemple #7
0
        internal uint data1(uint opcode)
        {
            uint Rd  = (opcode >> 8) & 0x07;
            uint imm = opcode & 0x00ff;
            uint result;

            switch (opcode & 0x1800)
            {
            case 0x0000:
                //MOV (1)
                result = imm;
                CPSR.set_NZ(result);
                mGPR[Rd] = result;
                break;

            case 0x0800:
            {        //CMP (1)
                uint op1 = get_reg(Rd);
                result = (op1 - imm);
                CPSR.set_flags_sub(op1, imm, result, true);
            } break;

            case 0x1000:
            {        //ADD (2)
                uint op1 = get_reg(Rd);
                result = (op1 + imm);
                CPSR.set_flags_add(op1, imm, result, false);
                mGPR[Rd] = result;
            } break;

            case 0x1800:
            {        //SUB (2)
                uint op1 = get_reg(Rd);
                result = (op1 - imm);
                CPSR.set_flags_sub(op1, imm, result, true);
                mGPR[Rd] = result;
            } break;
            } //switch
            return(1);
        }     //data1
Exemple #8
0
        /*----------------------------------------------------------------------------*/



        //----------------------------------------------------------------------------
        internal uint normal_data_op(uint op_code, uint operation)
        {
            //extract the S bit value from the opcode
            bool SBit = ((op_code & s_mask) != 0);

            //extract destination register from opcode
            uint Rd = ((op_code & rd_mask) >> 12);

            //extract operand register and get first operand
            uint Rn = ((op_code & rn_mask) >> 16);
            uint a  = get_reg(Rn);

            bool shift_carry = false;

            uint b;

            if ((op_code & imm_mask) == 0)
            {
                b = b_reg(op_code & op2_mask, ref shift_carry);
            }
            else
            {
                b = b_immediate(op_code & op2_mask, ref shift_carry);
            }

            uint rd = 0;

            switch (operation)                                               /* R15s @@?! */
            {
            case 0x0: rd = a & b; break;                                     //AND

            case 0x1: rd = a ^ b; break;                                     //EOR

            case 0x2: rd = a - b; break;                                     //SUB

            case 0x3: rd = b - a; break;                                     //RSB

            case 0x4: rd = a + b; break;                                     //ADD

            case 0x5: rd = a + b;                                            //ADC
                if (CPSR.cf)
                {
                    ++rd;
                }
                break;

            case 0x6: rd = a - b - 1;                                                   //SBC
                if (CPSR.cf)
                {
                    ++rd;
                }
                break;

            case 0x7: rd = b - a - 1;                                                   //RSC
                if (CPSR.cf)
                {
                    ++rd;
                }
                break;

            case 0x8: rd = a & b; break;                                        //TST

            case 0x9: rd = a ^ b; break;                                        //TEQ

            case 0xa: rd = a - b; break;                                        //CMP

            case 0xb: rd = a + b; break;                                        //CMN

            case 0xc: rd = a | b; break;                                        //ORR

            case 0xd: rd = b; break;                                            //MOV

            case 0xe: rd = a & ~b; break;                                       //BIC

            case 0xf: rd = ~b; break;                                           //MVN
            }//switch

            if ((operation & 0xc) != 0x8)                                                       //Return result unless a compare
            {
                //write result into destination register
                mGPR[Rd] = rd;

                //if S bit is set and if the destination register is r15(pc) then this instruction has
                //special meaning. We are returning from a non-user mode to user-mode.
                //ie  movs pc,r14
                if (SBit && (Rd == GeneralPurposeRegisters.PCRegisterIndex))
                {
                    CPSR.RestoreCPUMode();
                    return(1);
                } //if
            }     //if

            //if S bit is not set, we do not need to set any cpu flags, so we are done here
            if (!SBit)
            {
                return(1);
            }

            switch (operation)
            {                                                           //LOGICALs
            case 0x0:                                                   //AND
            case 0x1:                                                   //EOR
            case 0x8:                                                   //TST
            case 0x9:                                                   //TEQ
            case 0xc:                                                   //ORR
            case 0xd:                                                   //MOV
            case 0xe:                                                   //BIC
            case 0xf:                                                   //MVN
                CPSR.set_NZ(rd);
                CPSR.cf = shift_carry;
                break;

            case 0x2:                                                   //SUB
            case 0xa:                                                   //CMP
                CPSR.set_flags_sub(a, b, rd, true);
                break;

            case 0x6:                                                   //SBC
                CPSR.set_flags_sub(a, b, rd, CPSR.cf);
                break;

            case 0x3:                                                   //RSB
                CPSR.set_flags_sub(b, a, rd, true);
                break;

            case 0x7:                                                   //RSC
                CPSR.set_flags_sub(b, a, rd, CPSR.cf);
                break;

            case 0x4:                                                   //ADD
            case 0xb:                                                   //CMN
                CPSR.set_flags_add(a, b, rd, false);
                break;

            case 0x5:                                                   //ADC
                CPSR.set_flags_add(a, b, rd, CPSR.cf);
                break;

            default: break;
            } //switch
            return(1);
        }     //normal_data_op
Exemple #9
0
        /// <summary>
        /// Perform the ARM instruction MUL
        /// </summary>
        /// <param name="op_code"></param>
        /// <returns></returns>
        internal uint multiply(uint opcode)
        {
            uint Rs = ((opcode & rs_mask) >> 8);
            uint Rm = (opcode & rm_mask);
            uint Rd = ((opcode & rd_mask) >> 12);
            uint Rn = ((opcode & rn_mask) >> 16);

            uint RsData = get_reg(Rs);
            uint RmData = get_reg(Rm);
            uint M      = calculateMultM(RsData);

            if ((opcode & mul_long_bit) == 0)
            {//Normal:mla,mul
                uint cycles = 1;
                uint acc    = (RmData * RsData);
                if ((opcode & mul_acc_bit) != 0)
                {
                    acc += get_reg(Rd);
                    ++cycles;
                }
                mGPR[Rn] = acc;

                if ((opcode & s_mask) != 0)
                {
                    CPSR.set_NZ(acc);//flags
                }
                return(cycles + M);
            }//if
            else
            {//Long:xMLAL,xMULL
                uint cycles = 2;
                bool sign   = false;

                if ((opcode & 0x00400000) != 0)
                {//Signed
                    if (Utils.msb(RmData))
                    {
                        RmData = ~RmData + 1;
                        sign   = true;
                    }
                    if (Utils.msb(RsData))
                    {
                        RsData = ~RsData + 1;
                        sign   = !sign;
                    }
                }//if

                //Everything now `positive
                uint tl = (RmData & 0x0000ffff) * (RsData & 0x0000ffff);
                uint th = ((RmData >> 16) & 0X0000ffff) * ((RsData >> 16) & 0X0000ffff);
                uint tm = ((RmData >> 16) & 0X0000ffff) * (RsData & 0X0000ffff);

                RmData = ((RsData >> 16) & 0X0000ffff) * (RmData & 0X0000ffff);  /* Rm no longer needed */
                tm     = tm + RmData;
                if (tm < RmData)
                {
                    th = th + 0X00010000;                                    /* Propagate carry */
                }
                tl = tl + (tm << 16);
                if (tl < (tm << 16))
                {
                    th = th + 1;
                }
                th = th + ((tm >> 16) & 0X0000ffff);

                if (sign)
                {
                    th = ~th;
                    tl = ~tl + 1;
                    if (tl == 0)
                    {
                        th = th + 1;
                    }
                }

                if ((opcode & mul_acc_bit) != 0)
                {
                    ++cycles;
                    tm = tl + get_reg(Rd);
                    if (tm < tl)
                    {
                        th = th + 1;//Propagate carry
                    }
                    tl  = tm;
                    th += get_reg(Rn);
                }

                mGPR[Rd] = tl;
                mGPR[Rn] = th;

                if ((opcode & s_mask) != 0)
                {
                    CPSR.set_NZ(th | (((tl >> 16) | tl) & 0x0000ffff));
                }
                return(cycles + M);
            } //else
        }     //multiply
Exemple #10
0
        }        //stm

        /// <summary>
        /// LDM - perform a multi-register load from memory
        /// </summary>
        /// <returns>Number of clock cycles executed</returns>
        internal uint ldm(uint opcode)
        {
            uint mode         = (opcode & 0x01800000) >> 23;              //isolate PU bits
            uint Rn           = (opcode & rn_mask) >> 16;                 //get base register
            uint reg_list     = opcode & 0x0000ffff;                      //get the register list
            bool writeback    = (opcode & write_back_mask) != 0;          //determine writeback flag
            bool userModeLoad = ((opcode & 0x00400000) != 0);             //get user mode load flag

            uint address = Utils.valid_address(get_reg(Rn));              //make sure it is word aligned.
            int  first_reg;
            uint count      = bit_count(reg_list, out first_reg);
            bool includesPC = ((reg_list & 0x00008000) != 0);

            uint new_base;

            switch (mode)
            {
            case 0: new_base = address - 4 * count; address = new_base + 4; break;                      //DA (Decrement After)

            case 1: new_base = address + 4 * count; break;                                              //IA (Increment After)

            case 2: new_base = address - 4 * count; address = new_base; break;                          //DB (Decrement Before)

            case 3: new_base = address + 4 * count; address = address + 4; break;                       //IB (Increment Before)

            default: return(0);
            }            //switch

            if (writeback)
            {
                mGPR[Rn] = new_base;
            }

            uint reg         = 0;
            uint extraCycles = 0;

            //check
            while (reg_list != 0)
            {
                if (Utils.lsb(reg_list))
                {
                    uint data = this.GetMemory(address, ARMPluginInterfaces.MemorySize.Word);
                    if (reg == GeneralPurposeRegisters.PCRegisterIndex)
                    {                    //We are loading a new value into the PC, check if entering Thumb or ARM mode
                        extraCycles = 2;

                        //if the user mode flag is set and r15 is being loaded, we are executing
                        //LDM(3) and returning from an exception. We may be returning to Thumb mode or
                        //ARM mode. In each case, force align the returning address.
                        if (userModeLoad)
                        {                                  //we are returning from an exception, check if returning to ARM or Thumb mode
                            if ((CPSR.SPSR & 0x0020) != 0) //check thumb bit of saved CPSR
                            {
                                data = data & 0xfffffffe;  //returning to thumb mode, force align HWord
                            }
                            else
                            {
                                data = data & 0xfffffffc;                                   //returning to arm mode, force align Word
                            }
                        }
                        else if ((data & 0x01) != 0)
                        {                        //Entering Thumb mode. Make sure destination address is HWord aligned
                            CPSR.tf = true;
                            data    = data & 0xfffffffe;
                        }                        //if
                        else
                        {                        //Entering ARM mode. Make sure destination address is Word aligned
                            CPSR.tf = false;
                            data    = data & 0xfffffffc;
                        }                //else
                    }                    //if

                    if (userModeLoad & !includesPC)
                    {
                        mGPR.SetUserModeRegister(reg, data);
                    }
                    else
                    {
                        mGPR[reg] = data;
                    }

                    address += 4;
                }                //if
                reg_list >>= 1;
                ++reg;
            }            //while

            //if the PC was loaded during this instruction and the user mode load was specified
            //then we are returning from an exception.
            if (includesPC && userModeLoad)
            {
                CPSR.RestoreCPUMode();
            }

            return(2 + count + extraCycles);
        }        //ldm
Exemple #11
0
        }//data0(Thumb)

        internal uint data_transfer(uint opcode)
        {
            if ((opcode & 0x1000) == 0)
            {         //NOT load/store
                if ((opcode & 0x0800) == 0)
                {     //NOT load literal pool
                    if ((opcode & 0x0400) == 0)
                    { //Data processing
                        uint Rd = (opcode & 0x07);
                        uint Rm = ((opcode >> 3) & 7);

                        uint op1 = get_reg(Rd);
                        uint op2 = get_reg(Rm);
                        uint result;

                        //data processing opcode
                        switch (opcode & 0x03c0)
                        {
                        case 0x0000:
                            //AND
                            result = op1 & op2;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                            break;

                        case 0x0040:
                            //EOR
                            result = op1 ^ op2;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                            break;

                        case 0x0080:
                        {
                            //LSL(2)
                            bool cf = CPSR.cf;
                            result  = lsl(op1, op2 & 0x00ff, ref cf);
                            CPSR.cf = cf;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                        } break;

                        case 0x00c0:
                            //LSR(2)
                        {
                            bool cf = CPSR.cf;
                            result  = lsr(op1, op2 & 0x00ff, ref cf);
                            CPSR.cf = cf;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                        } break;

                        case 0x0100:
                            //ASR (2)
                        {
                            bool cf = CPSR.cf;
                            result  = asr(op1, op2 & 0x00ff, ref cf);
                            CPSR.cf = cf;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                        } break;

                        case 0x0140:
                            //ADC
                            result = op1 + op2;
                            if (CPSR.cf)
                            {
                                result++;    //Add CF
                            }
                            CPSR.set_flags_add(op1, op2, result, CPSR.cf);
                            mGPR[Rd] = result;
                            break;

                        case 0x0180:
                            //SBC
                            result = op1 - op2 - 1;
                            if (CPSR.cf)
                            {
                                result++;    //Add CF
                            }
                            CPSR.set_flags_sub(op1, op2, result, CPSR.cf);
                            mGPR[Rd] = result;
                            break;

                        case 0x01c0:
                        {        //ROR
                            bool cf = CPSR.cf;
                            result  = ror(op1, op2 & 0x00ff, ref cf);
                            CPSR.cf = cf;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                        } break;

                        case 0x0200:
                            //TST
                            CPSR.set_NZ(op1 & op2);
                            break;

                        case 0x0240:
                            //NEG
                            result = (uint)(0 - (int)op2);
                            CPSR.set_flags_sub(0, op2, result, true);
                            mGPR[Rd] = result;
                            break;

                        case 0x0280:
                            //CMP(2)
                            CPSR.set_flags_sub(op1, op2, op1 - op2, true);
                            break;

                        case 0x02c0:
                            //CMN
                            CPSR.set_flags_add(op1, op2, op1 + op2, false);
                            break;

                        case 0x0300:
                            //ORR
                            result = op1 | op2;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                            break;

                        case 0x0340:
                            //MUL
                            result = op1 * op2;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                            break;

                        case 0x0380:
                            //BIC
                            result = op1 & ~op2;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                            break;

                        case 0x03c0:
                            //MVN
                            result = ~op2;
                            CPSR.set_NZ(result);
                            mGPR[Rd] = result;
                            break;
                        }//switch
                    }
                    else
                    {//special data processing -- NO FLAG UPDATE
                        //ADD(4),CMP(3),MOV(2),BX,BLX
                        uint Rd = ((opcode & 0x0080) >> 4) | (opcode & 0x07);
                        uint Rm = ((opcode >> 3) & 15);

                        switch (opcode & 0x0300)
                        {
                        case 0x0000:
                            //ADD (4) high registers
                            mGPR[Rd] = get_reg(Rd) + get_reg(Rm);
                            break;

                        case 0x0100:
                        {        //CMP (3) high registers
                            uint op1 = get_reg(Rd);
                            uint op2 = get_reg(Rm);
                            CPSR.set_flags_sub(op1, op2, op1 - op2, true);
                        } break;

                        case 0x0200:
                        {        //MOV (2) high registers
                            uint op2 = get_reg(Rm);
                            if (Rd == GeneralPurposeRegisters.PCRegisterIndex)
                            {
                                op2 = op2 & 0xfffffffe;        //Tweak mov to PC
                            }
                            mGPR[Rd] = op2;
                        } break;

                        case 0x0300:
                        {        //BX/BLX Rm
                            bool link = ((opcode & 0x0080) != 0);
                            old_bx((opcode >> 3) & 0x0f, link);
                        } break;
                        }//switch
                    }
                }
                else
                {//load from literal pool -- LDR PC
                    uint Rd      = ((opcode >> 8) & 0x07);
                    uint address = (((opcode & 0x00ff) << 2)) + (get_reg(GeneralPurposeRegisters.PCRegisterIndex) & 0xfffffffc);
                    mGPR[Rd] = GetMemory(address, ARMPluginInterfaces.MemorySize.Word);
                }//else
            }
            else
            {
                data_transfer_load_store(opcode);
            }
            return(1);
        }//data_transfer(Thumb)
Exemple #12
0
        }//thumb_branch1

        internal uint data0(uint opcode)
        {
            if ((opcode & 0x1800) != 0x1800)
            {                                        //Either LSL,LSR or ASR
                uint Rm    = ((opcode >> 3) & 0x07); //Source register
                uint Rd    = (opcode & 0x07);        //Destination register
                uint shift = ((opcode >> 6) & 0x1f); //Shift value

                uint result = 0;
                bool cf     = (this.CPSR.cf);

                switch (opcode & 0X1800)
                {
                case 0x0000:
                    //LSL(1)
                    result = lsl(get_reg(Rm), shift, ref cf);
                    break;

                case 0x0800:
                    //LSR(1)
                    //A shift value of 0 means shift by 32
                    if (shift == 0)
                    {
                        shift = 32;
                    }
                    result = lsr(get_reg(Rm), shift, ref cf);
                    break;

                case 0x1000:
                    //ASR(1)
                    //A shift value of 0 means shift by 32
                    if (shift == 0)
                    {
                        shift = 32;
                    }
                    result = asr(get_reg(Rm), shift, ref cf);
                    break;

                default:
                    //Can't get here, but just in case
                    return(1);
                }//switch
                this.CPSR.cf = cf;
                this.CPSR.set_NZ(result);
                mGPR[Rd] = result;
            }//if
            else
            {//Either ADD or SUB
                uint Rd = (opcode & 0x07);              //Destination register
                uint Rn = ((opcode >> 3) & 0x07);
                uint Rm = ((opcode >> 6) & 0x07);

                uint op2;
                if ((opcode & 0x0400) == 0)
                {//ADD(3) or SUB(3)
                    op2 = get_reg(Rm);
                }
                else
                {//ADD(1) or SUB(1)
                    op2 = Rm;
                }

                uint result;
                uint op1 = get_reg(Rn);
                if ((opcode & 0x0200) == 0)
                {
                    result = op1 + op2;
                    CPSR.set_flags_add(op1, op2, result, false);
                }
                else
                {
                    result = op1 - op2;
                    CPSR.set_flags_sub(op1, op2, result, true);
                } //else
                mGPR[Rd] = result;
            }     //else

            return(1);
        }//data0(Thumb)
Exemple #13
0
 internal void DataOpHandleSetFlagsAWC_CMP(uint opcode, uint Rd, AWCResult awcResult)
 {
     //The CPSR is set the same way for all AWC-based instructions (the only difference
     //is the input to AWC).
     CPSR.set_NZCV((awcResult.result & 0x80000000) != 0, awcResult.result == 0, awcResult.carry_out, awcResult.overflow);
 }
Exemple #14
0
 internal void DataOpHandleSetFlagsLogical_CMP(uint opcode, uint Rd, uint result, bool shift_carry)
 {
     //The CPSR is always set the same way for logical operations
     //cf. MOV (ARMv7 A8.8.102)
     CPSR.set_NZCV((result & 0x80000000) != 0, result == 0, shift_carry, CPSR.vf);
 }
 /// <summary>
 /// GeneralPurposeRegisters ctor
 /// Requires a reference to the cpsr for current operating mode
 /// </summary>
 /// <param name="cpsr">the simulation CPSR register</param>
 public GeneralPurposeRegisters(CPSR cpsr)
 {
     _cpsr = cpsr;
     this.Reset();
 }