diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h index 11b3739..890bf6c 100644 --- a/src/iss/arch/riscv_hart_m_p.h +++ b/src/iss/arch/riscv_hart_m_p.h @@ -252,8 +252,11 @@ public: return 0b100010001000; // only machine mode is supported } + constexpr bool has_compressed() { + return traits::MISA_VAL&0b0100; + } constexpr reg_t get_pc_mask() { - return traits::MISA_VAL&0b0100?~1:~3; + return has_compressed()?~1:~3; } riscv_hart_m_p(feature_config cfg = feature_config{}); @@ -435,7 +438,7 @@ riscv_hart_m_p::riscv_hart_m_p(feature_config cfg) csr_rd_cb[addr] = &this_class::read_null; csr_wr_cb[addr] = &this_class::write_csr_reg; } - for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){ + if(traits::XLEN==32) for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){ csr_rd_cb[addr] = &this_class::read_null; csr_wr_cb[addr] = &this_class::write_csr_reg; } @@ -446,7 +449,7 @@ riscv_hart_m_p::riscv_hart_m_p(feature_config cfg) for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){ csr_rd_cb[addr] = &this_class::read_null; } - for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){ + if(traits::XLEN==32) for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){ csr_rd_cb[addr] = &this_class::read_null; //csr_wr_cb[addr] = &this_class::write_csr_reg; } @@ -469,12 +472,12 @@ riscv_hart_m_p::riscv_hart_m_p(feature_config cfg) csr_rd_cb[mcycle] = &this_class::read_cycle; csr_wr_cb[mcycle] = &this_class::write_cycle; - csr_rd_cb[mcycleh] = &this_class::read_cycle; - csr_wr_cb[mcycleh] = &this_class::write_cycle; + if(traits::XLEN==32) csr_rd_cb[mcycleh] = &this_class::read_cycle; + if(traits::XLEN==32) csr_wr_cb[mcycleh] = &this_class::write_cycle; csr_rd_cb[minstret] = &this_class::read_instret; csr_wr_cb[minstret] = &this_class::write_instret; - csr_rd_cb[minstreth] = &this_class::read_instret; - csr_wr_cb[minstreth] = &this_class::write_instret; + if(traits::XLEN==32) csr_rd_cb[minstreth] = &this_class::read_instret; + if(traits::XLEN==32) csr_wr_cb[minstreth] = &this_class::write_instret; csr_rd_cb[mstatus] = &this_class::read_status; csr_wr_cb[mstatus] = &this_class::write_status; csr_rd_cb[mcause] = &this_class::read_cause; @@ -633,7 +636,7 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce try { switch (space) { case traits::MEM: { - auto alignment = is_fetch(access)? (traits::MISA_VAL&0x100? 2 : 4) : length; + auto alignment = is_fetch(access)? (has_compressed()? 2 : 4) : length; if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; if (is_debug(access)) throw trap_access(0, addr); @@ -869,7 +872,6 @@ template iss::status riscv_hart_m_p if (addr == mcycle) { val = static_cast(cycle_val); } else if (addr == mcycleh) { - if (sizeof(typename traits::reg_t) != 4) return iss::Err; val = static_cast(cycle_val >> 32); } return iss::Ok; @@ -877,8 +879,6 @@ template iss::status riscv_hart_m_p template iss::status riscv_hart_m_p::write_cycle(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { - if (addr == mcycleh) - return iss::Err; mcycle_csr = static_cast(val); } else { if (addr == mcycle) { @@ -895,7 +895,6 @@ template iss::status riscv_hart_m_p if ((addr&0xff) == (minstret&0xff)) { val = static_cast(this->instret); } else if ((addr&0xff) == (minstreth&0xff)) { - if (sizeof(typename traits::reg_t) != 4) return iss::Err; val = static_cast(this->instret >> 32); } return iss::Ok; @@ -903,8 +902,6 @@ template iss::status riscv_hart_m_p template iss::status riscv_hart_m_p::write_instret(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { - if ((addr&0xff) == (minstreth&0xff)) - return iss::Err; this->instret = static_cast(val); } else { if ((addr&0xff) == (minstret&0xff)) { @@ -1244,7 +1241,7 @@ template uint64_t riscv_hart_m_p::e csr[mtval] = static_cast(addr); break; case 2: - csr[mtval] = (instr & 0x3)==3?instr:instr&0xffff; + csr[mtval] = (!has_compressed() || (instr & 0x3)==3)?instr:instr&0xffff; break; case 3: if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) { diff --git a/src/iss/arch/riscv_hart_mu_p.h b/src/iss/arch/riscv_hart_mu_p.h index 1b828fe..c896701 100644 --- a/src/iss/arch/riscv_hart_mu_p.h +++ b/src/iss/arch/riscv_hart_mu_p.h @@ -193,8 +193,11 @@ public: return m[mode]; } + constexpr bool has_compressed() { + return traits::MISA_VAL&0b0100; + } constexpr reg_t get_pc_mask() { - return traits::MISA_VAL&0b0100?~1:~3; + return has_compressed()?~1:~3; } riscv_hart_mu_p(feature_config cfg = feature_config{}); @@ -379,7 +382,7 @@ riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) csr_rd_cb[addr] = &this_class::read_null; csr_wr_cb[addr] = &this_class::write_csr_reg; } - for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){ + if(traits::XLEN==32) for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){ csr_rd_cb[addr] = &this_class::read_null; csr_wr_cb[addr] = &this_class::write_csr_reg; } @@ -390,7 +393,7 @@ riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){ csr_rd_cb[addr] = &this_class::read_null; } - for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){ + if(traits::XLEN==32) for (unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr){ csr_rd_cb[addr] = &this_class::read_null; //csr_wr_cb[addr] = &this_class::write_csr_reg; } @@ -414,12 +417,12 @@ riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) csr_rd_cb[mcycle] = &this_class::read_cycle; csr_wr_cb[mcycle] = &this_class::write_cycle; - csr_rd_cb[mcycleh] = &this_class::read_cycle; - csr_wr_cb[mcycleh] = &this_class::write_cycle; + if(traits::XLEN==32) csr_rd_cb[mcycleh] = &this_class::read_cycle; + if(traits::XLEN==32) csr_wr_cb[mcycleh] = &this_class::write_cycle; csr_rd_cb[minstret] = &this_class::read_instret; csr_wr_cb[minstret] = &this_class::write_instret; - csr_rd_cb[minstreth] = &this_class::read_instret; - csr_wr_cb[minstreth] = &this_class::write_instret; + if(traits::XLEN==32) csr_rd_cb[minstreth] = &this_class::read_instret; + if(traits::XLEN==32) csr_wr_cb[minstreth] = &this_class::write_instret; csr_rd_cb[mstatus] = &this_class::read_status; csr_wr_cb[mstatus] = &this_class::write_status; csr_rd_cb[mcause] = &this_class::read_cause; @@ -713,7 +716,7 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc return iss::Err; } } - auto alignment = is_fetch(access)? (traits::MISA_VAL&0x100? 2 : 4) : length; + auto alignment = is_fetch(access)? (has_compressed()? 2 : 4) : length; if (unlikely(is_fetch(access) && (addr&(alignment-1)))) { fault_data = addr; if (is_debug(access)) throw trap_access(0, addr); @@ -957,7 +960,6 @@ template iss::status riscv_hart_mu_p(cycle_val); } else if (addr == mcycleh) { - if (sizeof(typename traits::reg_t) != 4) return iss::Err; val = static_cast(cycle_val >> 32); } return iss::Ok; @@ -965,8 +967,6 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_cycle(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { - if (addr == mcycleh) - return iss::Err; mcycle_csr = static_cast(val); } else { if (addr == mcycle) { @@ -983,7 +983,6 @@ template iss::status riscv_hart_mu_p(this->instret); } else if ((addr&0xff) == (minstreth&0xff)) { - if (sizeof(typename traits::reg_t) != 4) return iss::Err; val = static_cast(this->instret >> 32); } return iss::Ok; @@ -991,8 +990,6 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_instret(unsigned addr, reg_t val) { if (sizeof(typename traits::reg_t) != 4) { - if ((addr&0xff) == (minstreth&0xff)) - return iss::Err; this->instret = static_cast(val); } else { if ((addr&0xff) == (minstret&0xff)) { @@ -1369,7 +1366,7 @@ template uint64_t riscv_hart_mu_p:: csr[utval | (new_priv << 8)] = static_cast(addr); break; case 2: - csr[utval | (new_priv << 8)] = (instr & 0x3)==3?instr:instr&0xffff; + csr[utval | (new_priv << 8)] = (!has_compressed() || (instr & 0x3)==3)?instr:instr&0xffff; break; case 3: if((FEAT & FEAT_DEBUG) && (csr[dcsr] & 0x8000)) {