| Line 5... | 
        Line 5... | 
      
      
         * @brief      RISC-V extension-M.
  | 
         * @brief      RISC-V extension-M.
  | 
      
      
         */
  | 
         */
  | 
      
      
         
  | 
         
  | 
      
      
        #include "api_utils.h"
  | 
        #include "api_utils.h"
  | 
      
      
        #include "riscv-isa.h"
  | 
        #include "riscv-isa.h"
  | 
      
      
        #include "instructions.h"
  | 
        #include "cpu_riscv_func.h"
  | 
      
      
         
  | 
         
  | 
      
      
        namespace debugger {
  | 
        namespace debugger {
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief The DIV signed division
  | 
         * @brief The DIV signed division
  | 
      
      
         */
  | 
         */
  | 
      
      
        class DIV : public IsaProcessor {
  | 
        class DIV : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            DIV() : IsaProcessor("DIV", "0000001??????????100?????0110011") {}
  | 
            DIV(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "DIV", "0000001??????????100?????0110011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                if (data->regs[u.bits.rs2]) {
  | 
                if (R[u.bits.rs2]) {
  | 
      
      
                    data->regs[u.bits.rd] = static_cast<int64_t>(data->regs[u.bits.rs1])
  | 
                    R[u.bits.rd] = static_cast<int64_t>(R[u.bits.rs1])
  | 
      
      
                         / static_cast<int64_t>(data->regs[u.bits.rs2]);
  | 
                         / static_cast<int64_t>(R[u.bits.rs2]);
  | 
      
      
                } else {
  | 
                } else {
  | 
      
      
                    data->regs[u.bits.rd] = 0;
  | 
                    R[u.bits.rd] = 0;
  | 
      
      
                }
  | 
                }
  | 
      
      
                data->npc = data->pc + 4;
  | 
                return 4;
  | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief DIVU unsigned division
  | 
         * @brief DIVU unsigned division
  | 
      
      
         */
  | 
         */
  | 
      
      
        class DIVU : public IsaProcessor {
  | 
        class DIVU : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            DIVU() : IsaProcessor("DIVU", "0000001??????????101?????0110011") {}
  | 
            DIVU(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "DIVU", "0000001??????????101?????0110011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                if (data->regs[u.bits.rs2]) {
  | 
                if (R[u.bits.rs2]) {
  | 
      
      
                    data->regs[u.bits.rd] =
  | 
                    R[u.bits.rd] = R[u.bits.rs1] / R[u.bits.rs2];
  | 
      
      
                        data->regs[u.bits.rs1] / data->regs[u.bits.rs2];
  | 
           | 
      
      
                } else {
  | 
                } else {
  | 
      
      
                    data->regs[u.bits.rd] = 0;
  | 
                    R[u.bits.rd] = 0;
  | 
      
      
                }
  | 
                }
  | 
      
      
                data->npc = data->pc + 4;
  | 
                return 4;
  | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief DIVUW 32-bits unsigned division (RV64I)
  | 
         * @brief DIVUW 32-bits unsigned division (RV64I)
  | 
      
      
         */
  | 
         */
  | 
      
      
        class DIVUW : public IsaProcessor {
  | 
        class DIVUW : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            DIVUW() : IsaProcessor("DIVUW", "0000001??????????101?????0111011") {}
  | 
            DIVUW(CpuRiver_Functional *icpu) :
  | 
      
      
           | 
                RiscvInstruction(icpu, "DIVUW", "0000001??????????101?????0111011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                if (static_cast<uint32_t>(data->regs[u.bits.rs2])) {
  | 
                if (static_cast<uint32_t>(R[u.bits.rs2])) {
  | 
      
      
                    data->regs[u.bits.rd] =
  | 
                    R[u.bits.rd] =
  | 
      
      
                        static_cast<uint32_t>(data->regs[u.bits.rs1]) /
  | 
                        static_cast<uint32_t>(R[u.bits.rs1]) /
  | 
      
      
                        static_cast<uint32_t>(data->regs[u.bits.rs2]);
  | 
                        static_cast<uint32_t>(R[u.bits.rs2]);
  | 
      
      
                } else {
  | 
                } else {
  | 
      
      
                    data->regs[u.bits.rd] = 0;
  | 
                    R[u.bits.rd] = 0;
  | 
      
      
                }
  | 
                }
  | 
      
      
                data->npc = data->pc + 4;
  | 
                return 4;
  | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief DIVW 32-bits signed division (RV64I)
  | 
         * @brief DIVW 32-bits signed division (RV64I)
  | 
      
      
         */
  | 
         */
  | 
      
      
        class DIVW : public IsaProcessor {
  | 
        class DIVW : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            DIVW() : IsaProcessor("DIVW", "0000001??????????100?????0111011") {}
  | 
            DIVW(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "DIVW", "0000001??????????100?????0111011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                int32_t divident = static_cast<int32_t>(data->regs[u.bits.rs1]);
  | 
                int32_t divident = static_cast<int32_t>(R[u.bits.rs1]);
  | 
      
      
                int32_t divisor = static_cast<int32_t>(data->regs[u.bits.rs2]);
  | 
                int32_t divisor = static_cast<int32_t>(R[u.bits.rs2]);
  | 
      
      
                if (divisor) {
  | 
                if (divisor) {
  | 
      
      
                    data->regs[u.bits.rd] = static_cast<int64_t>(divident / divisor);
  | 
                    R[u.bits.rd] = static_cast<int64_t>(divident / divisor);
  | 
      
      
                } else {
  | 
                } else {
  | 
      
      
                    data->regs[u.bits.rd] = 0;
  | 
                    R[u.bits.rd] = 0;
  | 
      
      
                }
  | 
                }
  | 
      
      
                data->npc = data->pc + 4;
  | 
                return 4;
  | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief The MUL signed multiplication
  | 
         * @brief The MUL signed multiplication
  | 
      
      
         *
  | 
         *
  | 
      
      
         * MUL performs an XLEN-bit XLEN-bit multiplication and places the lower XLEN
  | 
         * MUL performs an XLEN-bit XLEN-bit multiplication and places the lower XLEN
  | 
      
      
         * bits in the destination register.
  | 
         * bits in the destination register.
  | 
      
      
         */
  | 
         */
  | 
      
      
        class MUL : public IsaProcessor {
  | 
        class MUL : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            MUL() : IsaProcessor("MUL", "0000001??????????000?????0110011") {}
  | 
            MUL(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "MUL", "0000001??????????000?????0110011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                data->regs[u.bits.rd] = static_cast<int64_t>(data->regs[u.bits.rs1])
  | 
                R[u.bits.rd] = static_cast<int64_t>(R[u.bits.rs1])
  | 
      
      
                        * static_cast<int64_t>(data->regs[u.bits.rs2]);
  | 
                        * static_cast<int64_t>(R[u.bits.rs2]);
  | 
      
      
                data->npc = data->pc + 4;
  | 
                return 4;
  | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief The MULW 32-bits signed multiplication (RV64I)
  | 
         * @brief The MULW 32-bits signed multiplication (RV64I)
  | 
      
      
        | Line 119... | 
        Line 123... | 
      
      
         * registers, placing the sign-extension of the lower 32 bits of the result
  | 
         * registers, placing the sign-extension of the lower 32 bits of the result
  | 
      
      
         * into the destination register. MUL can be used to obtain the upper 32 bits
  | 
         * into the destination register. MUL can be used to obtain the upper 32 bits
  | 
      
      
         * of the 64-bit product, but signed arguments must be proper 32-bit signed
  | 
         * of the 64-bit product, but signed arguments must be proper 32-bit signed
  | 
      
      
         * values, whereas unsigned arguments must have their upper 32 bits clear.
  | 
         * values, whereas unsigned arguments must have their upper 32 bits clear.
  | 
      
      
         */
  | 
         */
  | 
      
      
        class MULW : public IsaProcessor {
  | 
        class MULW : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            MULW() : IsaProcessor("MULW", "0000001??????????000?????0111011") {}
  | 
            MULW(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "MULW", "0000001??????????000?????0111011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                int32_t m1 = static_cast<int32_t>(data->regs[u.bits.rs1]);
  | 
                int32_t m1 = static_cast<int32_t>(R[u.bits.rs1]);
  | 
      
      
                int32_t m2 = static_cast<int32_t>(data->regs[u.bits.rs2]);
  | 
                int32_t m2 = static_cast<int32_t>(R[u.bits.rs2]);
  | 
      
      
         
  | 
         
  | 
      
      
                data->regs[u.bits.rd] = static_cast<int64_t>(m1 * m2);
  | 
                R[u.bits.rd] = static_cast<int64_t>(m1 * m2);
  | 
      
      
                if (data->regs[u.bits.rd] & (1LL << 31)) {
  | 
                if (R[u.bits.rd] & (1LL << 31)) {
  | 
      
      
                    data->regs[u.bits.rd] |= EXT_SIGN_32;
  | 
                    R[u.bits.rd] |= EXT_SIGN_32;
  | 
      
      
                }
  | 
                }
  | 
      
      
                data->npc = data->pc + 4;
  | 
                return 4;
  | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief The REM (remainder of the corresponding signed division operation)
  | 
         * @brief The REM (remainder of the corresponding signed division operation)
  | 
      
      
         */
  | 
         */
  | 
      
      
        class REM : public IsaProcessor {
  | 
        class REM : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            REM() : IsaProcessor("REM", "0000001??????????110?????0110011") {}
  | 
            REM(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "REM", "0000001??????????110?????0110011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                data->regs[u.bits.rd] = static_cast<int64_t>(data->regs[u.bits.rs1])
  | 
                R[u.bits.rd] = static_cast<int64_t>(R[u.bits.rs1])
  | 
      
      
                     % static_cast<int64_t>(data->regs[u.bits.rs2]);
  | 
                     % static_cast<int64_t>(R[u.bits.rs2]);
  | 
      
      
                data->npc = data->pc + 4;
  | 
                return 4;
  | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief The REMU (remainder of the corresponding unsgined division operation)
  | 
         * @brief The REMU (remainder of the corresponding unsgined division operation)
  | 
      
      
         */
  | 
         */
  | 
      
      
        class REMU : public IsaProcessor {
  | 
        class REMU : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            REMU() : IsaProcessor("REMU", "0000001??????????111?????0110011") {}
  | 
            REMU(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "REMU", "0000001??????????111?????0110011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                data->regs[u.bits.rd] =
  | 
                R[u.bits.rd] = R[u.bits.rs1] % R[u.bits.rs2];
  | 
      
      
                    data->regs[u.bits.rs1] % data->regs[u.bits.rs2];
  | 
                return 4;
  | 
      
      
                data->npc = data->pc + 4;
  | 
           | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        /**
  | 
        /**
  | 
      
      
         * @brief REMW signed reminder operation
  | 
         * @brief REMW signed reminder operation
  | 
      
      
        | Line 177... | 
        Line 183... | 
      
      
         * REMW and REMUW instructions are only valid
  | 
         * REMW and REMUW instructions are only valid
  | 
      
      
         * for RV64, and provide the corresponding signed and unsigned remainder
  | 
         * for RV64, and provide the corresponding signed and unsigned remainder
  | 
      
      
         * operations respectively.
  | 
         * operations respectively.
  | 
      
      
         * Both REMW and REMUW sign-extend the 32-bit result to 64 bits.
  | 
         * Both REMW and REMUW sign-extend the 32-bit result to 64 bits.
  | 
      
      
         */
  | 
         */
  | 
      
      
        class REMW : public IsaProcessor {
  | 
        class REMW : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            REMW() : IsaProcessor("REMW", "0000001??????????110?????0111011") {}
  | 
            REMW(CpuRiver_Functional *icpu)
  | 
      
      
           | 
                : RiscvInstruction(icpu, "REMW", "0000001??????????110?????0111011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                int32_t tmp;
  | 
                int32_t tmp;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                tmp = static_cast<int32_t>(data->regs[u.bits.rs1])
  | 
                tmp = static_cast<int32_t>(R[u.bits.rs1])
  | 
      
      
                    % static_cast<int32_t>(data->regs[u.bits.rs2]);
  | 
                    % static_cast<int32_t>(R[u.bits.rs2]);
  | 
      
      
                data->regs[u.bits.rd] =
  | 
                R[u.bits.rd] = static_cast<uint64_t>(static_cast<int64_t>(tmp));
  | 
      
      
                    static_cast<uint64_t>(static_cast<int64_t>(tmp));
  | 
                return 4;
  | 
      
      
                data->npc = data->pc + 4;
  | 
           | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        class REMUW : public IsaProcessor {
  | 
        class REMUW : public RiscvInstruction {
  | 
      
      
        public:
  | 
        public:
  | 
      
      
            REMUW() : IsaProcessor("REMUW", "0000001??????????111?????0111011") {}
  | 
            REMUW(CpuRiver_Functional *icpu) :
  | 
      
      
           | 
                RiscvInstruction(icpu, "REMUW", "0000001??????????111?????0111011") {}
  | 
      
      
         
  | 
         
  | 
      
      
            virtual void exec(uint32_t *payload, CpuContextType *data) {
  | 
            virtual int exec(Reg64Type *payload) {
  | 
      
      
                ISA_R_type u;
  | 
                ISA_R_type u;
  | 
      
      
                uint32_t tmp;
  | 
                uint32_t tmp;
  | 
      
      
                u.value = payload[0];
  | 
                u.value = payload->buf32[0];
  | 
      
      
                tmp = static_cast<uint32_t>(data->regs[u.bits.rs1])
  | 
                tmp = static_cast<uint32_t>(R[u.bits.rs1])
  | 
      
      
                    % static_cast<uint32_t>(data->regs[u.bits.rs2]);
  | 
                    % static_cast<uint32_t>(R[u.bits.rs2]);
  | 
      
      
                data->regs[u.bits.rd] =
  | 
                R[u.bits.rd] = static_cast<uint64_t>(static_cast<int64_t>(tmp));
  | 
      
      
                    static_cast<uint64_t>(static_cast<int64_t>(tmp));
  | 
                return 4;
  | 
      
      
                data->npc = data->pc + 4;
  | 
           | 
      
      
            }
  | 
            }
  | 
      
      
        };
  | 
        };
  | 
      
      
         
  | 
         
  | 
      
      
        void addIsaExtensionM(CpuContextType *data, AttributeType *out) {
  | 
        void CpuRiver_Functional::addIsaExtensionM() {
  | 
      
      
            addSupportedInstruction(new DIV, out);
  | 
            addSupportedInstruction(new DIV(this));
  | 
      
      
            addSupportedInstruction(new DIVU, out);
  | 
            addSupportedInstruction(new DIVU(this));
  | 
      
      
            addSupportedInstruction(new DIVUW, out);
  | 
            addSupportedInstruction(new DIVUW(this));
  | 
      
      
            addSupportedInstruction(new DIVW, out);
  | 
            addSupportedInstruction(new DIVW(this));
  | 
      
      
            addSupportedInstruction(new MUL, out);
  | 
            addSupportedInstruction(new MUL(this));
  | 
      
      
            addSupportedInstruction(new MULW, out);
  | 
            addSupportedInstruction(new MULW(this));
  | 
      
      
            addSupportedInstruction(new REM, out);
  | 
            addSupportedInstruction(new REM(this));
  | 
      
      
            addSupportedInstruction(new REMU, out);
  | 
            addSupportedInstruction(new REMU(this));
  | 
      
      
            addSupportedInstruction(new REMW, out);
  | 
            addSupportedInstruction(new REMW(this));
  | 
      
      
            addSupportedInstruction(new REMUW, out);
  | 
            addSupportedInstruction(new REMUW(this));
  | 
      
      
           | 
         
  | 
      
      
            // TODO
  | 
            // TODO
  | 
      
      
            /*
  | 
            /*
  | 
      
      
            addInstr("MULH",               "0000001??????????001?????0110011", NULL, out);
  | 
            addInstr("MULH",               "0000001??????????001?????0110011", NULL, out);
  | 
      
      
            addInstr("MULHSU",             "0000001??????????010?????0110011", NULL, out);
  | 
            addInstr("MULHSU",             "0000001??????????010?????0110011", NULL, out);
  | 
      
      
            addInstr("MULHU",              "0000001??????????011?????0110011", NULL, out);
  | 
            addInstr("MULHU",              "0000001??????????011?????0110011", NULL, out);
  | 
      
      
            */
  | 
            */
  | 
      
      
            data->csr[CSR_misa] |= (1LL << ('M' - 'A'));
  | 
         
  | 
      
      
           | 
            uint64_t isa = portCSR_.read(CSR_misa).val;
  | 
      
      
           | 
            portCSR_.write(CSR_misa, isa | (1LL << ('M' - 'A')));
  | 
      
      
        }
  | 
        }
  | 
      
      
         
  | 
         
  | 
      
      
        }  // namespace debugger
  | 
        }  // namespace debugger
  | 
      
      
         
  | 
         
  | 
      
      
         No newline at end of file
  | 
         No newline at end of file
  |