Exemple #1
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 #2
0
 internal void RegisterDataOpMultiply(DataOpMultiplyLongRaw opHandler, uint base_opcode, bool supports_setflags, string basename)
 {
     RegisterOpcode(base_opcode, 0xf00fff0f, delegate(uint opcode) { return(ExecuteDataOpMultiplyLong(opHandler, opcode, false)); }, basename);
     if (supports_setflags)
     {
         RegisterOpcode(base_opcode | s_mask, 0xf00fff0f, delegate(uint opcode) { return(ExecuteDataOpMultiplyLong(opHandler, opcode, true)); }, basename + "S");
     }
 }