From: Luke Kenneth Casson Leighton Date: Sat, 29 Sep 2018 09:19:47 +0000 (+0100) Subject: a LOT of debugging and fixing, sv loop actually working X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e44b1d76caa001ebc23db05b69acb74f6016b690;p=riscv-isa-sim.git a LOT of debugging and fixing, sv loop actually working --- diff --git a/riscv/encoding.h b/riscv/encoding.h index 4fd7b36..980a792 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -1262,6 +1262,22 @@ DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_R DECLARE_CSR(svvl, CSR_SVVL) DECLARE_CSR(svrealvl, CSR_SVREALVL) DECLARE_CSR(svmvl, CSR_SVMVL) +DECLARE_CSR(svregcfg0, CSR_SVREGCFG0) +DECLARE_CSR(svregcfg1, CSR_SVREGCFG1) +DECLARE_CSR(svregcfg2, CSR_SVREGCFG2) +DECLARE_CSR(svregcfg3, CSR_SVREGCFG3) +DECLARE_CSR(svregcfg4, CSR_SVREGCFG4) +DECLARE_CSR(svregcfg5, CSR_SVREGCFG5) +DECLARE_CSR(svregcfg6, CSR_SVREGCFG6) +DECLARE_CSR(svregcfg7, CSR_SVREGCFG7) +DECLARE_CSR(svpredcfg0, CSR_SVPREDCFG0) +DECLARE_CSR(svpredcfg1, CSR_SVPREDCFG1) +DECLARE_CSR(svpredcfg2, CSR_SVPREDCFG2) +DECLARE_CSR(svpredcfg3, CSR_SVPREDCFG3) +DECLARE_CSR(svpredcfg4, CSR_SVPREDCFG4) +DECLARE_CSR(svpredcfg5, CSR_SVPREDCFG5) +DECLARE_CSR(svpredcfg6, CSR_SVPREDCFG6) +DECLARE_CSR(svpredcfg7, CSR_SVPREDCFG7) DECLARE_CSR(fflags, CSR_FFLAGS) DECLARE_CSR(frm, CSR_FRM) DECLARE_CSR(fcsr, CSR_FCSR) diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index 4b7a41a..3ff09e8 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -1,5 +1,8 @@ // See LICENSE for license details. +#define xstr(s) str(s) +#define str(s) #s + reg_t FN(processor_t* p, insn_t s_insn, reg_t pc) { int xlen = ISASZ; @@ -21,38 +24,44 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc) // really could do with a macro for-loop here... oh well... // integer ops, RD, RS1, RS2, RS3 (use sv_int_tb) bool vectorop = -#ifdef USING_RD - insn.check_reg(true, s_insn.rd()) | +#ifdef USING_REG_RD + insn.sv_check_reg(true, s_insn.rd()) | #endif -#ifdef USING_RS1 - insn.check_reg(true, s_insn.rs1()) | +#ifdef USING_REG_RS1 + insn.sv_check_reg(true, s_insn.rs1()) | #endif -#ifdef USING_RS2 - insn.check_reg(true, s_insn.rs2()) | +#ifdef USING_REG_RS2 + insn.sv_check_reg(true, s_insn.rs2()) | #endif -#ifdef USING_RS2 - insn.check_reg(true, s_insn.rs3()) | +#ifdef USING_REG_RS2 + insn.sv_check_reg(true, s_insn.rs3()) | #endif // fp ops, RD, RS1, RS2, RS3 (use sv_fp_tb) -#ifdef USING_FRD - insn.check_reg(false, s_insn.frd()) | +#ifdef USING_REG_FRD + insn.sv_check_reg(false, s_insn.rd()) | #endif -#ifdef USING_FRS1 - insn.check_reg(false, s_insn.frs1()) | +#ifdef USING_REG_FRS1 + insn.sv_check_reg(false, s_insn.rs1()) | #endif -#ifdef USING_FRS2 - insn.check_reg(false, s_insn.rs2()) | +#ifdef USING_REG_FRS2 + insn.sv_check_reg(false, s_insn.rs2()) | #endif -#ifdef USING_FRS2 - insn.check_reg(false, s_insn.rs3()) | +#ifdef USING_REG_FRS2 + insn.sv_check_reg(false, s_insn.rs3()) | #endif false; // save a few cycles by |ing the checks together. + if (insn.sv_check_reg(true, 16)) + { + fprintf(stderr, "reg %s %x rd %ld rs1 %ld rs2 %ld\n", + xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2()); + } // if vectorop is set, one of the regs is not a scalar, // so we must read the VL CSR and do a loop if (vectorop) { - // TODO: vlen = p->CSR(SIMPLEV_VL); // something like that... + vlen = p->get_state()->vl; + fprintf(stderr, "vectorop %x vlen %d\n", INSNCODE, vlen); } for (int voffs=0; voffs < vlen; voffs++) { diff --git a/riscv/insns/csrrwi.h b/riscv/insns/csrrwi.h index 8793d31..7b70600 100644 --- a/riscv/insns/csrrwi.h +++ b/riscv/insns/csrrwi.h @@ -1,4 +1,6 @@ +fprintf(stderr, "csrrwi %lx\n", insn.csr()); int csr = validate_csr(insn.csr(), true); +fprintf(stderr, "validated %x\n", csr); #ifdef SPIKE_SIMPLEV reg_t old = 0; // stop compiler bitchin if (csr != CSR_SVVL) diff --git a/riscv/processor.cc b/riscv/processor.cc index b5ae099..7c17432 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -333,18 +333,20 @@ void processor_t::set_csr(int which, reg_t val) reg_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | ((ext != NULL) << IRQ_COP); reg_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP; + fprintf(stderr, "set CSR %x %lx\n", which, val); switch (which) { #ifdef SPIKE_SIMPLEV case CSR_SVMVL: state.mvl = std::min(val, (uint64_t)63); // limited to XLEN width + fprintf(stderr, "set MVL %lx\n", state.mvl); break; case CSR_SVREALVL: state.vl = std::min(val, state.mvl); // limited to MVL break; case CSR_SVVL: state.vl = std::min(state.mvl, val); - state.XPR.write(val, state.vl); + fprintf(stderr, "set VL %lx\n", state.vl); break; case CSR_SVREGCFG0: case CSR_SVREGCFG1: @@ -357,6 +359,7 @@ void processor_t::set_csr(int which, reg_t val) { // identify which (pair) of SV config CAM registers are being set int tbidx = (which - CSR_SVREGCFG0) * 2; + fprintf(stderr, "set REGCFG %d %lx\n", tbidx, val); // lower 16 bits go into even, upper into odd... state.sv_csrs[tbidx].u = get_field(val, 0xffff); state.sv_csrs[tbidx+1].u = get_field(val, 0xffff0000); @@ -364,6 +367,7 @@ void processor_t::set_csr(int which, reg_t val) // when it comes to context-switching, it's clear what needs to be saved for (int i = tbidx+2; i < 16; i++) { + fprintf(stderr, "clr REGCFG %d\n", i); state.sv_csrs[i].u = 0; } // okaaay and now "unpack" the CAM to make it easier to use. this @@ -375,8 +379,12 @@ void processor_t::set_csr(int which, reg_t val) for (int i = 0; i < SV_CSR_SZ; i++) { union sv_reg_csr_entry *c = &state.sv_csrs[i]; - uint64_t idx = c->b.regidx; + uint64_t idx = c->b.regkey; sv_reg_entry *r; + if (c->u == 0) + { + break; + } // XXX damn. this basically duplicates sv_insn_t::get_regentry. if (c->b.type == 1) { @@ -391,6 +399,8 @@ void processor_t::set_csr(int which, reg_t val) r->isvec = c->b.isvec; r->packed = c->b.packed; r->active = true; + fprintf(stderr, "setting REGCFG type:%d isvec:%d %d %d\n", + c->b.type, r->isvec, (int)idx, (int)r->regidx); } break; } @@ -665,6 +675,15 @@ reg_t processor_t::get_csr(int which) return state.vl; case CSR_SVMVL: return state.mvl; + case CSR_SVREGCFG0: + case CSR_SVREGCFG1: + case CSR_SVREGCFG2: + case CSR_SVREGCFG3: + case CSR_SVREGCFG4: + case CSR_SVREGCFG5: + case CSR_SVREGCFG6: + case CSR_SVREGCFG7: + return 0; #endif case CSR_FFLAGS: require_fp; diff --git a/riscv/sv.cc b/riscv/sv.cc index 4341363..ba7f691 100644 --- a/riscv/sv.cc +++ b/riscv/sv.cc @@ -44,6 +44,7 @@ bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg) } if (r->active && r->isvec) { + fprintf(stderr, "checkreg: %ld active\n", reg); return true; } return false; diff --git a/riscv/sv.h b/riscv/sv.h index 93f3fcf..9315dd0 100644 --- a/riscv/sv.h +++ b/riscv/sv.h @@ -11,7 +11,7 @@ // all entries with a higher index union sv_reg_csr_entry { struct { - unsigned int type : 1; // 0=INT, 1=FP + unsigned int type : 1; // 1=INT, 0=FP uint64_t regkey : 5; // 5 bits unsigned int elwidth: 2; // 0=8-bit, 1=dflt, 2=dflt/2 3=dflt*2 uint64_t regidx : 6; // yes 6 bits @@ -44,7 +44,7 @@ typedef struct { union sv_pred_csr_entry { struct { - unsigned int type : 1; // 0=INT, 1=FP + unsigned int type : 1; // 1=INT, 0=FP uint64_t regkey: 5; // 5 bits unsigned int zero : 1; // zeroing=1, skipping=0 unsigned int inv : 1; // inversion=1