From b3e5bb2b68377b628ff86aaedb7d307f84a1ec0e Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 25 Oct 2018 06:36:06 +0100 Subject: [PATCH] use reg_spec_t which passes reg + offset into sv_proc_t --- riscv/insn_template_sv.cc | 24 ++++++++-------- riscv/insns/c_add.h | 2 +- riscv/insns/c_jal.h | 3 +- riscv/insns/c_jalr.h | 5 ++-- riscv/insns/c_jr.h | 2 +- riscv/insns/c_lui.h | 2 +- riscv/insns/c_lwsp.h | 2 +- riscv/insns/c_mv.h | 2 +- riscv/insns/csrrc.h | 2 +- riscv/insns/csrrci.h | 4 +-- riscv/insns/csrrs.h | 2 +- riscv/insns/csrrsi.h | 4 +-- riscv/insns/csrrwi.h | 6 ++-- riscv/sv.cc | 58 +++++++++++++++++++++----------------- riscv/sv_decode.h | 51 ++++++++++++++++++--------------- riscv/sv_insn_redirect.cc | 59 ++++++++++++++++++++++++++++----------- riscv/sv_insn_redirect.h | 16 +++++++++-- 17 files changed, 150 insertions(+), 94 deletions(-) diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index 5bf0a0f..f8b5522 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -77,7 +77,7 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc) reg_t _target_reg = 0; reg_t *target_reg = NULL; #endif - reg_t sp = 0; + reg_spec_t sp = {0,0}; if (vlen > 0) { fprintf(stderr, "pre-ex reg %s %x %ld rd %ld rs1 %ld rs2 %ld vlen %d\n", @@ -107,14 +107,14 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc) #endif #ifdef INSN_CATEGORY_TWINPREDICATION #ifdef INSN_TYPE_C_STACK_LD - src_pred = insn.predicate(sp, SRC_PREDINT, zeroingsrc); + src_pred = insn.predicate(sp.reg, SRC_PREDINT, zeroingsrc); #else src_pred = insn.predicate(s_insn.SRC_REG(), SRC_PREDINT, zeroingsrc); #endif #endif #ifdef DEST_PREDINT #ifdef INSN_TYPE_C_STACK_ST - dest_pred = insn.predicate(sp, DEST_PREDINT, zeroing); + dest_pred = insn.predicate(sp.reg, DEST_PREDINT, zeroing); #else // use the ORIGINAL, i.e. NON-REDIRECTED, register here dest_pred = insn.predicate(s_insn.DEST_REG(), DEST_PREDINT, zeroing); @@ -186,24 +186,24 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc) "vlen %d stop %d pred %lx rdv %lx v %ld rvc2 %ld sp %lx\n", xstr(INSN), INSNCODE, voffs, *src_offs, *dest_offs, vlen, insn.stop_vloop(), - dest_pred & (1<get_csr(csr); if (write) { diff --git a/riscv/insns/csrrci.h b/riscv/insns/csrrci.h index 35ac85f..9bf2c62 100644 --- a/riscv/insns/csrrci.h +++ b/riscv/insns/csrrci.h @@ -1,8 +1,8 @@ -bool write = insn.rs1() != 0; +bool write = insn.insn_t::rs1() != 0; int csr = validate_csr(insn.csr(), write); reg_t old = p->get_csr(csr); if (write) { - p->set_csr(csr, old & ~(reg_t)insn.rs1()); + p->set_csr(csr, old & ~(reg_t)insn.insn_t::rs1()); } WRITE_RD(sext_xlen(sv_reg_t(old))); serialize(); diff --git a/riscv/insns/csrrs.h b/riscv/insns/csrrs.h index f3f1166..3680f4e 100644 --- a/riscv/insns/csrrs.h +++ b/riscv/insns/csrrs.h @@ -1,4 +1,4 @@ -bool write = insn.rs1() != 0; +bool write = insn.insn_t::rs1() != 0; int csr = validate_csr(insn.csr(), write); sv_reg_t old = sv_reg_t(p->get_csr(csr)); if (write) { diff --git a/riscv/insns/csrrsi.h b/riscv/insns/csrrsi.h index a065261..adda6be 100644 --- a/riscv/insns/csrrsi.h +++ b/riscv/insns/csrrsi.h @@ -1,8 +1,8 @@ -bool write = insn.rs1() != 0; +bool write = insn.insn_t::rs1() != 0; int csr = validate_csr(insn.csr(), write); reg_t old = p->get_csr(csr); if (write) { - p->set_csr(csr, old | insn.rs1()); + p->set_csr(csr, old | insn.insn_t::rs1()); } WRITE_RD(sext_xlen(sv_reg_t(old))); serialize(); diff --git a/riscv/insns/csrrwi.h b/riscv/insns/csrrwi.h index eaeecd5..7e1c4f7 100644 --- a/riscv/insns/csrrwi.h +++ b/riscv/insns/csrrwi.h @@ -6,17 +6,17 @@ reg_t old = 0; // stop compiler bitchin if (csr != CSR_USVVL && csr != CSR_USVMVL) { old = p->get_csr(csr); - p->set_csr(csr, insn.rs1()); + p->set_csr(csr, insn.insn_t::rs1()); } else if (csr == CSR_USVVL || csr == CSR_USVMVL) { - p->set_csr(csr, insn.rs1()+1); // must add one here + p->set_csr(csr, insn.insn_t::rs1()+1); // must add one here old = p->get_csr(csr); } #else reg_t old = p->get_csr(csr); -p->set_csr(csr, insn.rs1()); +p->set_csr(csr, insn.insn_t::rs1()); #endif WRITE_RD(sext_xlen(sv_reg_t(old))); serialize(); diff --git a/riscv/sv.cc b/riscv/sv.cc index 53abaf4..7c2f0a1 100644 --- a/riscv/sv.cc +++ b/riscv/sv.cc @@ -5,20 +5,20 @@ int get_bitwidth(uint8_t elwidth, int xlen) { switch (elwidth) { - case 0: return (xlen == 32)? 64 : 32; - case 1: return (xlen == 32)? 32 : 64; + case 0: return xlen; + case 1: return 8; case 2: return 16; - default: return 8; + default: return 32; } } sv_insn_t::sv_insn_t(processor_t *pr, bool _sv_enabled, - insn_bits_t bits, unsigned int f, int xlen, + insn_bits_t bits, unsigned int f, int _xlen, uint64_t &p_rd, uint64_t &p_rs1, uint64_t &p_rs2, uint64_t &p_rs3, uint64_t &p_sp, uint64_t *p_im, int *o_rd, int *o_rs1, int *o_rs2, int *o_rs3, int *o_sp, int *o_imm) : - insn_t(bits), p(pr), src_bitwidth(0), + insn_t(bits), p(pr), src_bitwidth(0), xlen(_xlen), sv_enabled(_sv_enabled), vloop_continue(false), at_least_one_reg_vectorised(false), fimap(f), offs_rd(o_rd), offs_rs1(o_rs1), offs_rs2(o_rs2), offs_rs3(o_rs3), @@ -35,31 +35,31 @@ sv_insn_t::sv_insn_t(processor_t *pr, bool _sv_enabled, { sv_reg_entry* r = NULL; if (bm == (REG_RS1 & fimap)) { - r = get_regentry(rs1(), true); + r = get_regentry(insn_t::rs1(), true); } else if (bm == (REG_RS2 & fimap)) { - r = get_regentry(rs2(), true); + r = get_regentry(insn_t::rs2(), true); } else if (bm == (REG_RS3 & fimap)) { - r = get_regentry(rs3(), true); + r = get_regentry(insn_t::rs3(), true); } else if (bm == (REG_RVC_RS1 & fimap)) { - r = get_regentry(rvc_rs1(), true); + r = get_regentry(insn_t::rvc_rs1(), true); } else if (bm == (REG_RVC_RS2 & fimap)) { - r = get_regentry(rvc_rs2(), true); + r = get_regentry(insn_t::rvc_rs2(), true); } else if (bm == (REG_RVC_RS1S & fimap)) { - r = get_regentry(rvc_rs1s(), true); + r = get_regentry(insn_t::rvc_rs1s(), true); } else if (bm == (REG_RVC_RS2S & fimap)) { - r = get_regentry(rvc_rs2s(), true); + r = get_regentry(insn_t::rvc_rs2s(), true); } else if (bm == (REG_FRS1 & fimap)) { - r = get_regentry(rs1(), false); + r = get_regentry(insn_t::rs1(), false); } else if (bm == (REG_FRS2 & fimap)) { - r = get_regentry(rs2(), false); + r = get_regentry(insn_t::rs2(), false); } else if (bm == (REG_FRS3 & fimap)) { - r = get_regentry(rs3(), false); + r = get_regentry(insn_t::rs3(), false); } if (r == NULL || !r->active) { continue; } uint8_t elwidth = r->elwidth; - uint8_t bitwidth = get_bitwidth(elwidth, xlen); + uint8_t bitwidth = get_bitwidth(elwidth, _xlen); src_bitwidth = std::max(src_bitwidth, bitwidth); } } @@ -130,8 +130,11 @@ bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg) * of SV. it's "supposed" to "just" be a vectorisation API. it isn't: * it's quite a bit more. */ -uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int voffs) +reg_spec_t sv_insn_t::remap(uint64_t reg, bool intreg, int voffs) { + reg_spec_t spec; + spec.reg = reg; + spec.offset = voffs; // okaay so first determine which map to use. intreg is passed // in (ultimately) from id_regs.py's examination of the use of // FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed @@ -142,7 +145,7 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int voffs) // is not being "redirected", so just return the actual reg. if (!r->active) { - return reg; // not active: return as-is + return spec; // not active: return as-is } vloop_continue = true; @@ -156,7 +159,7 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int voffs) // we return the re-mapped register... if (!r->isvec) // scalar { - return reg; + return spec; } vloop_continue = true; @@ -165,7 +168,8 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int voffs) // and, at last, we have "parallelism" a la contiguous registers. reg += voffs; // wheww :) - return reg; + spec.reg = reg; + return spec; } /* gets the predication value (if active). returns all-1s if not active @@ -215,14 +219,18 @@ reg_t sv_insn_t::predicate(uint64_t reg, bool intreg, bool &zeroing) return predicate; } -uint64_t sv_insn_t::predicated(uint64_t reg, int offs, uint64_t pred) +reg_spec_t sv_insn_t::predicated(reg_spec_t const& spec, int offs, uint64_t pred) { + reg_spec_t res = spec; + res.offset = offs; if (pred & (1<rd(), freg(value) ); + DO_WRITE_FREG( _insn->rd().reg, freg(value) ); } void (sv_proc_t::WRITE_FRD)(float64_t value) { fprintf(stderr, "WRITE_FRD float64_t %g\n", (double)value.v); - DO_WRITE_FREG( _insn->rd(), freg(value) ); + DO_WRITE_FREG( _insn->rd().reg, freg(value) ); } void (sv_proc_t::WRITE_FRD)(freg_t value) { fprintf(stderr, "WRITE_FRD fsv_reg_t %lx\n", value.v[0]); - DO_WRITE_FREG( _insn->rd(), freg(value) ); + DO_WRITE_FREG( _insn->rd().reg, freg(value) ); +} + +void (sv_proc_t::WRITE_RVC_FRS2S)(float32_t value) +{ + WRITE_FREG(_insn->rvc_rs2s().reg, freg(value)); +} + +void (sv_proc_t::WRITE_RVC_FRS2S)(float64_t const& value) +{ + WRITE_FREG(_insn->rvc_rs2s().reg, freg(value)); } //void (sv_proc_t::WRITE_RD)(bool value) @@ -69,10 +79,10 @@ void (sv_proc_t::WRITE_RD)(sv_reg_t const& value) // STATE.XPR.write(reg, value); //} -void (sv_proc_t::WRITE_REG)(reg_t reg, sv_reg_t const& value) +void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value) { //WRITE_REG( reg, value ); // XXX TODO: replace properly - STATE.XPR.write(reg, value); + STATE.XPR.write(spec.reg, value); } //void (sv_proc_t::WRITE_REG)(reg_t reg, uint64_t value) @@ -100,17 +110,18 @@ sv_reg_t (sv_proc_t::READ_REG)(uint64_t i) } */ -sv_reg_t sv_proc_t::get_intreg(reg_t reg) +sv_reg_t sv_proc_t::get_intreg(reg_spec_t const&spec) { - //uint8_t elwidth = _insn->reg_elwidth(reg, true); - uint64_t data = _insn->p->get_state()->XPR[reg]; - return sv_reg_t(data, xlen, _insn->src_bitwidth); + uint8_t elwidth = _insn->reg_elwidth(spec.reg, true); + uint64_t data = _insn->p->get_state()->XPR[spec.reg]; // XXX TODO: offset + uint8_t bitwidth = _insn->src_bitwidth; + return sv_reg_t(data, xlen, bitwidth); } #define GET_REG(name) \ sv_reg_t sv_proc_t::get_##name() \ { \ - reg_t reg = _insn->name (); \ + reg_spec_t reg = _insn->name (); \ return get_intreg(reg); \ } @@ -122,24 +133,40 @@ GET_REG(rvc_rs2s) GET_REG(rvc_rs1) GET_REG(rvc_rs2) +sv_reg_t sv_proc_t::get_rvc_sp() +{ + return get_intreg({X_SP, 0}); //_insn->rvc_sp()); // XXX TODO: work out redirection +} + freg_t sv_proc_t::get_frs1() { - return READ_FREG(_insn->rs1()); + reg_spec_t spec = _insn->rs1(); + return READ_FREG(spec.reg); +} + +freg_t sv_proc_t::get_frs3() +{ + return READ_FREG(_insn->rs3().reg); } freg_t sv_proc_t::get_frs2() { - return READ_FREG(_insn->rs2()); + return READ_FREG(_insn->rs2().reg); } -sv_reg_t sv_proc_t::get_shamt() +freg_t sv_proc_t::get_rvc_frs2s() { - return sv_reg_t(_insn->i_imm() & 0x3F); // XXX TODO: has to be elwidth'd + return READ_FREG(_insn->rvc_rs2s().reg); } -sv_reg_t sv_proc_t::get_rvc_sp() +freg_t sv_proc_t::get_rvc_frs2() { - return get_intreg(X_SP); // XXX TODO: work out redirection + return READ_FREG(_insn->rvc_rs2().reg); +} + +sv_reg_t sv_proc_t::get_shamt() +{ + return sv_reg_t(_insn->i_imm() & 0x3F); // XXX TODO: has to be elwidth'd } sv_reg_t sv_proc_t::uint64_max() diff --git a/riscv/sv_insn_redirect.h b/riscv/sv_insn_redirect.h index 4988ad5..af2b67f 100644 --- a/riscv/sv_insn_redirect.h +++ b/riscv/sv_insn_redirect.h @@ -11,14 +11,18 @@ #undef RS3 #undef FRS1 #undef FRS2 +#undef FRS3 #undef RVC_RS1 #undef RVC_RS2 +#undef RVC_FRS2 +#undef RVC_FRS2S #undef RVC_RS1S #undef RVC_RS2S #undef WRITE_REG #undef WRITE_FRD #undef WRITE_RVC_RS1S #undef WRITE_RVC_RS2S +#undef WRITE_RVC_FRS2S #undef WRITE_RD #undef RVC_SP #undef SHAMT @@ -33,11 +37,14 @@ class insn_t; #define FRS1 get_frs1() #define FRS2 get_frs2() +#define FRS3 get_frs3() #define RS1 get_rs1() #define RS2 get_rs2() #define RS3 get_rs3() #define RVC_RS1 get_rvc_rs1() #define RVC_RS2 get_rvc_rs2() +#define RVC_FRS2 get_rvc_frs2() +#define RVC_FRS2S get_rvc_frs2s() #define RVC_RS1S get_rvc_rs1s() #define RVC_RS2S get_rvc_rs2s() #define RVC_SP get_rvc_sp() @@ -58,11 +65,13 @@ public: void (WRITE_RD)(sv_reg_t const& value); // XXX TODO investigate //void (WRITE_RD)(sv_sreg_t value); // XXX TODO investigate void (WRITE_RVC_RS2S)(sv_reg_t const& value); // XXX TODO investigate + void (WRITE_RVC_FRS2S)(float64_t const& value); // XXX TODO investigate + void (WRITE_RVC_FRS2S)(float32_t value); // XXX TODO investigate //void (WRITE_RVC_RS2S)(sv_sreg_t value); // XXX TODO investigate void (WRITE_RVC_RS1S)(sv_reg_t const& value); // XXX TODO investigate //void (WRITE_RVC_RS1S)(sv_sreg_t value); // XXX TODO investigate //void (WRITE_REG)(reg_t reg, uint64_t value); - void (WRITE_REG)(reg_t reg, sv_reg_t const& value); + void (WRITE_REG)(reg_spec_t const®, sv_reg_t const& value); //void (WRITE_REG)(reg_t reg, sv_sreg_t value); void (WRITE_FRD)(freg_t value); void (WRITE_FRD)(float64_t value); @@ -88,7 +97,7 @@ public: } private: - sv_reg_t get_intreg(reg_t reg); + sv_reg_t get_intreg(reg_spec_t const®); public: sv_reg_t get_rs1(); @@ -107,6 +116,9 @@ public: freg_t get_frs1(); freg_t get_frs2(); + freg_t get_frs3(); + freg_t get_rvc_frs2(); + freg_t get_rvc_frs2s(); sv_sreg_t (sext_xlen)(sv_sreg_t const& v); // WARNING... sv_sreg_t (sext_xlen)(sv_reg_t const& v); // WARNING... -- 2.30.2