OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_fnc_plugin/] [riscv-ext-m.cpp] - Diff between revs 3 and 4

Show entire file | Details | Blame | View Log

Rev 3 Rev 4
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.