diff options
author | Scott Johnson <scott.johnson@arilinc.com> | 2021-09-24 22:02:14 -0700 |
---|---|---|
committer | Scott Johnson <scott.johnson@arilinc.com> | 2021-09-27 18:00:28 -0700 |
commit | 2b26a3cdf1cf391893a0a1a31815ac59d96ff05c (patch) | |
tree | 72bb3f45134ad2dce2c3135e9fa731fcdac6e8d7 /riscv | |
parent | ede97384f6f760a1a2c8b15f329e3e7c574a0301 (diff) | |
download | spike-2b26a3cdf1cf391893a0a1a31815ac59d96ff05c.zip spike-2b26a3cdf1cf391893a0a1a31815ac59d96ff05c.tar.gz spike-2b26a3cdf1cf391893a0a1a31815ac59d96ff05c.tar.bz2 |
Convert frm & fflags to csr_t
Adds proper logging of fflags on FP arithmetic ops.
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/csrs.cc | 16 | ||||
-rw-r--r-- | riscv/csrs.h | 9 | ||||
-rw-r--r-- | riscv/decode.h | 12 | ||||
-rw-r--r-- | riscv/insns/vfcvt_x_f_v.h | 6 | ||||
-rw-r--r-- | riscv/insns/vfcvt_xu_f_v.h | 6 | ||||
-rw-r--r-- | riscv/insns/vfmv_f_s.h | 2 | ||||
-rw-r--r-- | riscv/insns/vfmv_s_f.h | 2 | ||||
-rw-r--r-- | riscv/insns/vfncvt_x_f_w.h | 6 | ||||
-rw-r--r-- | riscv/insns/vfncvt_xu_f_w.h | 6 | ||||
-rw-r--r-- | riscv/insns/vfwcvt_x_f_v.h | 4 | ||||
-rw-r--r-- | riscv/insns/vfwcvt_xu_f_v.h | 4 | ||||
-rw-r--r-- | riscv/processor.cc | 38 | ||||
-rw-r--r-- | riscv/processor.h | 4 |
13 files changed, 56 insertions, 59 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 5060f48..461d4d1 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1116,3 +1116,19 @@ void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv) noexcept { this->prv = prv; log_write(); } + + +float_csr_t::float_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init): + masked_csr_t(proc, addr, mask, init) { +} + +void float_csr_t::verify_permissions(insn_t insn, bool write) const { + require_fp; + if (!proc->extension_enabled('F')) + throw trap_illegal_instruction(insn.bits()); +} + +bool float_csr_t::unlogged_write(const reg_t val) noexcept { + dirty_fp_state; + return masked_csr_t::unlogged_write(val); +} diff --git a/riscv/csrs.h b/riscv/csrs.h index fd20782..cf726a2 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -577,4 +577,13 @@ class dcsr_csr_t: public csr_t { typedef std::shared_ptr<dcsr_csr_t> dcsr_csr_t_p; + +class float_csr_t: public masked_csr_t { + public: + float_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); + virtual void verify_permissions(insn_t insn, bool write) const override; + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; + #endif diff --git a/riscv/decode.h b/riscv/decode.h index a54f1f0..2429ae7 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -234,7 +234,7 @@ private: #define BRANCH_TARGET (pc + insn.sb_imm()) #define JUMP_TARGET (pc + insn.uj_imm()) #define RM ({ int rm = insn.rm(); \ - if(rm == 7) rm = STATE.frm; \ + if(rm == 7) rm = STATE.frm->read(); \ if(rm > 4) throw trap_illegal_instruction(insn.bits()); \ rm; }) @@ -281,7 +281,7 @@ private: #define set_fp_exceptions ({ if (softfloat_exceptionFlags) { \ dirty_fp_state; \ - STATE.fflags |= softfloat_exceptionFlags; \ + STATE.fflags->write(STATE.fflags->read() | softfloat_exceptionFlags); \ } \ softfloat_exceptionFlags = 0; }) @@ -1848,12 +1848,12 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \ (P.VU.vsew == e32 && p->extension_enabled('F')) || \ (P.VU.vsew == e64 && p->extension_enabled('D'))); \ require_vector(true);\ - require(STATE.frm < 0x5);\ + require(STATE.frm->read() < 0x5);\ reg_t vl = P.VU.vl; \ reg_t rd_num = insn.rd(); \ reg_t rs1_num = insn.rs1(); \ reg_t rs2_num = insn.rs2(); \ - softfloat_roundingMode = STATE.frm; + softfloat_roundingMode = STATE.frm->read(); #define VI_VFP_LOOP_BASE \ VI_VFP_COMMON \ @@ -2264,12 +2264,12 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \ require((P.VU.vsew == e8 && p->extension_enabled(EXT_ZFH)) || \ (P.VU.vsew == e16 && p->extension_enabled('F')) || \ (P.VU.vsew == e32 && p->extension_enabled('D'))); \ - require(STATE.frm < 0x5);\ + require(STATE.frm->read() < 0x5);\ reg_t vl = P.VU.vl; \ reg_t rd_num = insn.rd(); \ reg_t rs1_num = insn.rs1(); \ reg_t rs2_num = insn.rs2(); \ - softfloat_roundingMode = STATE.frm; \ + softfloat_roundingMode = STATE.frm->read(); \ for (reg_t i=P.VU.vstart; i<vl; ++i){ \ VI_LOOP_ELEMENT_SKIP(); diff --git a/riscv/insns/vfcvt_x_f_v.h b/riscv/insns/vfcvt_x_f_v.h index 01e5ca1..7e507a3 100644 --- a/riscv/insns/vfcvt_x_f_v.h +++ b/riscv/insns/vfcvt_x_f_v.h @@ -1,11 +1,11 @@ // vfcvt.x.f.v vd, vd2, vm VI_VFP_VF_LOOP ({ - P.VU.elt<int16_t>(rd_num, i) = f16_to_i16(vs2, STATE.frm, true); + P.VU.elt<int16_t>(rd_num, i) = f16_to_i16(vs2, STATE.frm->read(), true); }, { - P.VU.elt<int32_t>(rd_num, i) = f32_to_i32(vs2, STATE.frm, true); + P.VU.elt<int32_t>(rd_num, i) = f32_to_i32(vs2, STATE.frm->read(), true); }, { - P.VU.elt<int64_t>(rd_num, i) = f64_to_i64(vs2, STATE.frm, true); + P.VU.elt<int64_t>(rd_num, i) = f64_to_i64(vs2, STATE.frm->read(), true); }) diff --git a/riscv/insns/vfcvt_xu_f_v.h b/riscv/insns/vfcvt_xu_f_v.h index 725cbda..51c00ca 100644 --- a/riscv/insns/vfcvt_xu_f_v.h +++ b/riscv/insns/vfcvt_xu_f_v.h @@ -1,11 +1,11 @@ // vfcvt.xu.f.v vd, vd2, vm VI_VFP_VV_LOOP ({ - P.VU.elt<uint16_t>(rd_num, i) = f16_to_ui16(vs2, STATE.frm, true); + P.VU.elt<uint16_t>(rd_num, i) = f16_to_ui16(vs2, STATE.frm->read(), true); }, { - P.VU.elt<uint32_t>(rd_num, i) = f32_to_ui32(vs2, STATE.frm, true); + P.VU.elt<uint32_t>(rd_num, i) = f32_to_ui32(vs2, STATE.frm->read(), true); }, { - P.VU.elt<uint64_t>(rd_num, i) = f64_to_ui64(vs2, STATE.frm, true); + P.VU.elt<uint64_t>(rd_num, i) = f64_to_ui64(vs2, STATE.frm->read(), true); }) diff --git a/riscv/insns/vfmv_f_s.h b/riscv/insns/vfmv_f_s.h index 3309e47..06d93b2 100644 --- a/riscv/insns/vfmv_f_s.h +++ b/riscv/insns/vfmv_f_s.h @@ -4,7 +4,7 @@ require_fp; require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZFH)) || (P.VU.vsew == e32 && p->extension_enabled('F')) || (P.VU.vsew == e64 && p->extension_enabled('D'))); -require(STATE.frm < 0x5); +require(STATE.frm->read() < 0x5); reg_t rs2_num = insn.rs2(); uint64_t vs2_0 = 0; diff --git a/riscv/insns/vfmv_s_f.h b/riscv/insns/vfmv_s_f.h index d12fd91..4e7f82e 100644 --- a/riscv/insns/vfmv_s_f.h +++ b/riscv/insns/vfmv_s_f.h @@ -4,7 +4,7 @@ require_fp; require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZFH)) || (P.VU.vsew == e32 && p->extension_enabled('F')) || (P.VU.vsew == e64 && p->extension_enabled('D'))); -require(STATE.frm < 0x5); +require(STATE.frm->read() < 0x5); reg_t vl = P.VU.vl; diff --git a/riscv/insns/vfncvt_x_f_w.h b/riscv/insns/vfncvt_x_f_w.h index a342e3f..a8a6dfb 100644 --- a/riscv/insns/vfncvt_x_f_w.h +++ b/riscv/insns/vfncvt_x_f_w.h @@ -2,15 +2,15 @@ VI_VFP_CVT_SCALE ({ auto vs2 = P.VU.elt<float16_t>(rs2_num, i); - P.VU.elt<int8_t>(rd_num, i, true) = f16_to_i8(vs2, STATE.frm, true); + P.VU.elt<int8_t>(rd_num, i, true) = f16_to_i8(vs2, STATE.frm->read(), true); }, { auto vs2 = P.VU.elt<float32_t>(rs2_num, i); - P.VU.elt<int16_t>(rd_num, i, true) = f32_to_i16(vs2, STATE.frm, true); + P.VU.elt<int16_t>(rd_num, i, true) = f32_to_i16(vs2, STATE.frm->read(), true); }, { auto vs2 = P.VU.elt<float64_t>(rs2_num, i); - P.VU.elt<int32_t>(rd_num, i, true) = f64_to_i32(vs2, STATE.frm, true); + P.VU.elt<int32_t>(rd_num, i, true) = f64_to_i32(vs2, STATE.frm->read(), true); }, { require(p->extension_enabled(EXT_ZFH)); diff --git a/riscv/insns/vfncvt_xu_f_w.h b/riscv/insns/vfncvt_xu_f_w.h index 6fda694..bff733e 100644 --- a/riscv/insns/vfncvt_xu_f_w.h +++ b/riscv/insns/vfncvt_xu_f_w.h @@ -2,15 +2,15 @@ VI_VFP_CVT_SCALE ({ auto vs2 = P.VU.elt<float16_t>(rs2_num, i); - P.VU.elt<uint8_t>(rd_num, i, true) = f16_to_ui8(vs2, STATE.frm, true); + P.VU.elt<uint8_t>(rd_num, i, true) = f16_to_ui8(vs2, STATE.frm->read(), true); }, { auto vs2 = P.VU.elt<float32_t>(rs2_num, i); - P.VU.elt<uint16_t>(rd_num, i, true) = f32_to_ui16(vs2, STATE.frm, true); + P.VU.elt<uint16_t>(rd_num, i, true) = f32_to_ui16(vs2, STATE.frm->read(), true); }, { auto vs2 = P.VU.elt<float64_t>(rs2_num, i); - P.VU.elt<uint32_t>(rd_num, i, true) = f64_to_ui32(vs2, STATE.frm, true); + P.VU.elt<uint32_t>(rd_num, i, true) = f64_to_ui32(vs2, STATE.frm->read(), true); }, { require(p->extension_enabled(EXT_ZFH)); diff --git a/riscv/insns/vfwcvt_x_f_v.h b/riscv/insns/vfwcvt_x_f_v.h index 60ebbca..5e0c064 100644 --- a/riscv/insns/vfwcvt_x_f_v.h +++ b/riscv/insns/vfwcvt_x_f_v.h @@ -5,11 +5,11 @@ VI_VFP_CVT_SCALE }, { auto vs2 = P.VU.elt<float16_t>(rs2_num, i); - P.VU.elt<int32_t>(rd_num, i, true) = f16_to_i32(vs2, STATE.frm, true); + P.VU.elt<int32_t>(rd_num, i, true) = f16_to_i32(vs2, STATE.frm->read(), true); }, { auto vs2 = P.VU.elt<float32_t>(rs2_num, i); - P.VU.elt<int64_t>(rd_num, i, true) = f32_to_i64(vs2, STATE.frm, true); + P.VU.elt<int64_t>(rd_num, i, true) = f32_to_i64(vs2, STATE.frm->read(), true); }, { ; diff --git a/riscv/insns/vfwcvt_xu_f_v.h b/riscv/insns/vfwcvt_xu_f_v.h index a6a0591..f3243c8 100644 --- a/riscv/insns/vfwcvt_xu_f_v.h +++ b/riscv/insns/vfwcvt_xu_f_v.h @@ -5,11 +5,11 @@ VI_VFP_CVT_SCALE }, { auto vs2 = P.VU.elt<float16_t>(rs2_num, i); - P.VU.elt<uint32_t>(rd_num, i, true) = f16_to_ui32(vs2, STATE.frm, true); + P.VU.elt<uint32_t>(rd_num, i, true) = f16_to_ui32(vs2, STATE.frm->read(), true); }, { auto vs2 = P.VU.elt<float32_t>(rs2_num, i); - P.VU.elt<uint64_t>(rd_num, i, true) = f32_to_ui64(vs2, STATE.frm, true); + P.VU.elt<uint64_t>(rd_num, i, true) = f32_to_ui64(vs2, STATE.frm->read(), true); }, { ; diff --git a/riscv/processor.cc b/riscv/processor.cc index b87d276..4727d0c 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -521,8 +521,8 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[addr] = std::make_shared<pmpcfg_csr_t>(proc, addr); } - fflags = 0; - frm = 0; + csrmap[CSR_FFLAGS] = fflags = std::make_shared<float_csr_t>(proc, CSR_FFLAGS, FSR_AEXC >> FSR_AEXC_SHIFT, 0); + csrmap[CSR_FRM] = frm = std::make_shared<float_csr_t>(proc, CSR_FRM, FSR_RD >> FSR_RD_SHIFT, 0); serialized = false; #ifdef RISCV_ENABLE_COMMITLOG @@ -977,18 +977,10 @@ void processor_t::set_csr(int which, reg_t val) case CSR_SENTROPY: es.set_sentropy(val); break; - case CSR_FFLAGS: - dirty_fp_state; - state.fflags = val & (FSR_AEXC >> FSR_AEXC_SHIFT); - break; - case CSR_FRM: - dirty_fp_state; - state.frm = val & (FSR_RD >> FSR_RD_SHIFT); - break; case CSR_FCSR: dirty_fp_state; - state.fflags = (val & FSR_AEXC) >> FSR_AEXC_SHIFT; - state.frm = (val & FSR_RD) >> FSR_RD_SHIFT; + state.fflags->write((val & FSR_AEXC) >> FSR_AEXC_SHIFT); + state.frm->write((val & FSR_RD) >> FSR_RD_SHIFT); break; case CSR_VCSR: dirty_vs_state; @@ -1012,16 +1004,6 @@ void processor_t::set_csr(int which, reg_t val) #if defined(RISCV_ENABLE_COMMITLOG) switch (which) { - case CSR_FFLAGS: - LOG_CSR(CSR_FFLAGS); - break; - case CSR_FRM: - LOG_CSR(CSR_FRM); - break; - case CSR_FCSR: - LOG_CSR(CSR_FFLAGS); - LOG_CSR(CSR_FRM); - break; case CSR_VCSR: LOG_CSR(CSR_VXSAT); LOG_CSR(CSR_VXRM); @@ -1071,21 +1053,11 @@ reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek) if (!write) break; ret(es.get_sentropy()); - case CSR_FFLAGS: - require_fp; - if (!extension_enabled('F')) - break; - ret(state.fflags); - case CSR_FRM: - require_fp; - if (!extension_enabled('F')) - break; - ret(state.frm); case CSR_FCSR: require_fp; if (!extension_enabled('F')) break; - ret((state.fflags << FSR_AEXC_SHIFT) | (state.frm << FSR_RD_SHIFT)); + ret((state.fflags->read() << FSR_AEXC_SHIFT) | (state.frm->read() << FSR_RD_SHIFT)); case CSR_VCSR: require_vector_vs; if (!extension_enabled('V')) diff --git a/riscv/processor.h b/riscv/processor.h index a9b75fd..fd16812 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -199,8 +199,8 @@ struct state_t static const int max_pmp = 16; pmpaddr_csr_t_p pmpaddr[max_pmp]; - uint32_t fflags; - uint32_t frm; + csr_t_p fflags; + csr_t_p frm; bool serialized; // whether timer CSRs are in a well-defined state // When true, execute a single instruction and then enter debug mode. This |