mcontrol[i].type = 2;
}
+int state_t::sv_csr_sz()
+{
+ if (prv == PRV_M)
+ return SV_MCSR_SZ;
+ if (prv == PRV_S)
+ return SV_SCSR_SZ;
+ return SV_UCSR_SZ;
+}
+sv_csr_t &state_t::sv()
+{
+ if (prv == PRV_M)
+ return get_msv();
+ if (prv == PRV_S)
+ return get_ssv();
+ return get_usv();
+}
+
void processor_t::set_debug(bool value)
{
debug = value;
{
#ifdef SPIKE_SIMPLEV
case CSR_USVMVL:
- state.mvl = std::min(val, (uint64_t)64); // limited to XLEN width
+ state.sv().mvl = std::min(val, (uint64_t)64); // limited to XLEN width
// TODO XXX throw exception if val == 0
- fprintf(stderr, "set MVL %lx\n", state.mvl);
+ fprintf(stderr, "set MVL %lx\n", state.sv().mvl);
break;
case CSR_USVSTATE:
// bits 0-5: mvl - 6-11: vl - 12-17: srcoffs - 18-23: destoffs
set_csr(CSR_USVMVL, get_field(val, 0x1f )+1);
set_csr(CSR_USVVL , get_field(val, 0x1f<<6)+1);
- state.srcoffs = std::min(get_field(val, 0x1f<<12), state.vl-1);
- state.destoffs = std::min(get_field(val, 0x1f<<18), state.vl-1);
+ state.sv().srcoffs = std::min(get_field(val, 0x1f<<12), state.sv().vl-1);
+ state.sv().destoffs = std::min(get_field(val, 0x1f<<18), state.sv().vl-1);
break;
case CSR_USVVL:
- state.vl = std::min(state.mvl, val);
+ state.sv().vl = std::min(state.sv().mvl, val);
// TODO XXX throw exception if val == 0
- fprintf(stderr, "set VL %lx\n", state.vl);
+ fprintf(stderr, "set VL %lx\n", state.sv().vl);
break;
case CSR_SVREGCFG0:
case CSR_SVREGCFG1:
int tbidx = (which - CSR_SVREGCFG0) * 2;
fprintf(stderr, "set REGCFG %d %lx\n", tbidx, v);
// lower 16 bits go into even, upper into odd...
- state.sv_csrs[tbidx].u = get_field(v, 0xffffUL);
- state.sv_csrs[tbidx+1].u = get_field(v, 0xffffUL<<16);
+ state.sv().sv_csrs[tbidx].u = get_field(v, 0xffffUL);
+ state.sv().sv_csrs[tbidx+1].u = get_field(v, 0xffffUL<<16);
int clroffset = 2;
if (xlen == 64)
{
- state.sv_csrs[tbidx+2].u = get_field(v, 0xffffUL<<32);
- state.sv_csrs[tbidx+3].u = get_field(v, 0xffffUL<<48);
+ state.sv().sv_csrs[tbidx+2].u = get_field(v, 0xffffUL<<32);
+ state.sv().sv_csrs[tbidx+3].u = get_field(v, 0xffffUL<<48);
clroffset = 4;
}
// clear out all CSRs above the one(s) being set: this ensures that
for (int i = tbidx+clroffset; i < 16; i++)
{
fprintf(stderr, "clr REGCFG %d\n", i);
- state.sv_csrs[i].u = 0;
+ state.sv().sv_csrs[i].u = 0;
}
// okaaay and now "unpack" the CAM to make it easier to use. this
// approach is not designed to be efficient right now. optimise later
// first clear the old tables
- memset(state.sv_int_tb, 0, sizeof(state.sv_int_tb));
- memset(state.sv_fp_tb, 0, sizeof(state.sv_fp_tb));
+ memset(state.sv().sv_int_tb, 0, sizeof(state.sv().sv_int_tb));
+ memset(state.sv().sv_fp_tb, 0, sizeof(state.sv().sv_fp_tb));
// now walk the CAM and unpack it
- for (int i = 0; i < SV_CSR_SZ; i++)
+ for (int i = 0; i < state.sv_csr_sz(); i++)
{
- union sv_reg_csr_entry *c = &state.sv_csrs[i];
+ union sv_reg_csr_entry *c = &state.sv().sv_csrs[i];
uint64_t idx = c->b.regkey;
sv_reg_entry *r;
if (c->u == 0)
// XXX damn. this basically duplicates sv_insn_t::get_regentry.
if (c->b.type == 1)
{
- r = &state.sv_int_tb[idx];
+ r = &state.sv().sv_int_tb[idx];
}
else
{
- r = &state.sv_fp_tb[idx];
+ r = &state.sv().sv_fp_tb[idx];
}
r->elwidth = c->b.elwidth;
r->regidx = c->b.regidx;
uint64_t v = (uint64_t)val;
int tbidx = (which - CSR_SVPREDCFG0) * 2;
fprintf(stderr, "set PREDCFG %d %lx\n", tbidx, v);
- state.sv_pred_csrs[tbidx].u = get_field(v, 0xffff);
- state.sv_pred_csrs[tbidx+1].u = get_field(v, 0xffff0000);
+ state.sv().sv_pred_csrs[tbidx].u = get_field(v, 0xffff);
+ state.sv().sv_pred_csrs[tbidx+1].u = get_field(v, 0xffff0000);
int clroffset = 2;
if (xlen == 64)
{
- state.sv_pred_csrs[tbidx+2].u = get_field(v, 0xffffUL<<32);
- state.sv_pred_csrs[tbidx+3].u = get_field(v, 0xffffUL<<48);
+ state.sv().sv_pred_csrs[tbidx+2].u = get_field(v, 0xffffUL<<32);
+ state.sv().sv_pred_csrs[tbidx+3].u = get_field(v, 0xffffUL<<48);
clroffset = 4;
}
for (int i = tbidx+clroffset; i < 16; i++)
{
- state.sv_pred_csrs[i].u = 0;
+ state.sv().sv_pred_csrs[i].u = 0;
}
- memset(state.sv_pred_int_tb, 0, sizeof(state.sv_pred_int_tb));
- memset(state.sv_pred_fp_tb, 0, sizeof(state.sv_pred_fp_tb));
- for (int i = 0; i < SV_CSR_SZ; i++)
+ memset(state.sv().sv_pred_int_tb, 0, sizeof(state.sv().sv_pred_int_tb));
+ memset(state.sv().sv_pred_fp_tb, 0, sizeof(state.sv().sv_pred_fp_tb));
+ for (int i = 0; i < state.sv_csr_sz(); i++)
{
- union sv_pred_csr_entry *c = &state.sv_pred_csrs[i];
+ union sv_pred_csr_entry *c = &state.sv().sv_pred_csrs[i];
uint64_t idx = c->b.regkey;
if (c->u == 0)
{
// XXX damn. this basically duplicates sv_insn_t::get_predentry.
if (c->b.type == 1)
{
- r = &state.sv_pred_int_tb[idx];
+ r = &state.sv().sv_pred_int_tb[idx];
}
else
{
- r = &state.sv_pred_fp_tb[idx];
+ r = &state.sv().sv_pred_fp_tb[idx];
}
r->regidx = c->b.regidx;
r->zero = c->b.zero;
{
#ifdef SPIKE_SIMPLEV
case CSR_USVVL:
- return state.vl;
+ return state.sv().vl;
case CSR_USVSTATE:
- return (state.vl-1) | ((state.mvl-1)<<6) |
- (state.srcoffs<<12) | (state.destoffs<<18) ;
+ return (state.sv().vl-1) | ((state.sv().mvl-1)<<6) |
+ (state.sv().srcoffs<<12) | (state.sv().destoffs<<18) ;
case CSR_USVMVL:
- return state.mvl;
+ return state.sv().mvl;
case CSR_SVREGCFG0:
case CSR_SVREGCFG1:
case CSR_SVREGCFG2:
}
}
}
+