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)
// 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;
// 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++)
{
+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)
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:
{
// 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);
// 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
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)
{
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;
}
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;
}
if (r->active && r->isvec)
{
+ fprintf(stderr, "checkreg: %ld active\n", reg);
return true;
}
return false;
// 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
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