// identify which regs have had their CSR entries set as vectorised.
// really could do with a macro for-loop here... oh well...
// integer ops, RD, RS1, RS2, RS3 (use sv_int_tb)
- if (insn.sv_check_reg(true, 16))
+ if (insn.sv_check_reg(true, 15))
{
fprintf(stderr, "reg %s %x rd %ld rs1 %ld rs2 %ld vlen %d\n",
xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2(),
for (int voffs=0; voffs < vlen; voffs++)
{
insn.reset_vloop_check();
+#ifdef INSN_C_MV
+ fprintf(stderr, "pre twin reg %s src %d dest %d pred %lx %lx vlen %d\n",
+ xstr(INSN), *src_offs, *dest_offs, src_pred, dest_pred, vlen);
+#endif
#ifdef INSN_C_BEQZ
fprintf(stderr, "pre twin reg %s src %lx dest %d pred %lx %lx\n",
xstr(INSN), _target_reg, *dest_offs, target_pred, dest_pred);
case CSR_SVREGCFG6:
case CSR_SVREGCFG7:
{
+ uint64_t v = (uint64_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);
+ 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(val, 0xffff);
- state.sv_csrs[tbidx+1].u = get_field(val, 0xffff<<16);
+ state.sv_csrs[tbidx].u = get_field(v, 0xffffUL);
+ state.sv_csrs[tbidx+1].u = get_field(v, 0xffffUL<<16);
int clroffset = 2;
if (xlen == 64)
{
- state.sv_csrs[tbidx+2].u = get_field(val, 0xffffUL<<32);
- state.sv_csrs[tbidx+3].u = get_field(val, 0xffffUL<<48);
+ state.sv_csrs[tbidx+2].u = get_field(v, 0xffffUL<<32);
+ state.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
{
// comments removed as it's near-identical to the regs version
// TODO: macro-ify
+ uint64_t v = (uint64_t)val;
int tbidx = (which - CSR_SVPREDCFG0) * 2;
- state.sv_pred_csrs[tbidx].u = get_field(val, 0xffff);
- state.sv_pred_csrs[tbidx+1].u = get_field(val, 0xffff0000);
+ 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);
int clroffset = 2;
if (xlen == 64)
{
- state.sv_pred_csrs[tbidx+2].u = get_field(val, 0xffffUL<<32);
- state.sv_pred_csrs[tbidx+3].u = get_field(val, 0xffffUL<<48);
+ state.sv_pred_csrs[tbidx+2].u = get_field(v, 0xffffUL<<32);
+ state.sv_pred_csrs[tbidx+3].u = get_field(v, 0xffffUL<<48);
clroffset = 4;
}
for (int i = tbidx+clroffset; i < 16; i++)
r->inv = c->b.inv;
r->packed = c->b.packed;
r->active = true;
- fprintf(stderr, "setting PREDCFG type:%d zero:%d %d %d\n",
- c->b.type, r->zero, (int)idx, (int)r->regidx);
+ fprintf(stderr, "setting PREDCFG %d type:%d zero:%d %d %d\n",
+ i, c->b.type, r->zero, (int)idx, (int)r->regidx);
}
break;
}
return ~0x0; // *PREDICATION* not active: return all-1s (unconditional "on")
}
zeroing = r->zero;
+ fprintf(stderr, "predicate read %ld -> %ld\n", reg, r->regidx);
reg = r->regidx;
reg_spec_t rs = {reg, NULL};
reg_t predicate = p->s.READ_REG(rs); // macros go through processor_t state
void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value)
{
+ uint64_t wval = (uint64_t)value;
//WRITE_REG( reg, value ); // XXX TODO: replace properly
reg_t reg = spec.reg;
+ int bitwidth = get_bitwidth(_insn->reg_elwidth(reg, true), xlen);
+ unsigned int shift = 0;
+ unsigned int offs = 0;
if (spec.offset) {
- reg += *spec.offset;
+ unsigned int nbytes = xlen / bitwidth;
+ offs = *spec.offset;
+ shift = offs % nbytes;
+ offs /= nbytes;
+ reg += offs;
}
- STATE.XPR.write(reg, value);
+ if (xlen != bitwidth)
+ {
+ uint64_t data = _insn->p->get_state()->XPR[reg];
+ uint64_t mask = ((1UL<<bitwidth)-1UL) << (shift*bitwidth);
+ wval = wval << (shift*bitwidth); // gets element within the reg-block
+ uint64_t ndata = data & (uint64_t)(~mask); // masks off the right bits
+ wval |= ndata;
+ fprintf(stderr, "writereg %d bitwidth %d offs %d shift %d %lx " \
+ " %lx %lx %lx\n",
+ spec.reg, bitwidth, offs, shift, data,
+ ndata, mask, wval);
+ }
+ STATE.XPR.write(reg, wval);
}
freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec)
reg_t reg = spec.reg;
int bitwidth = get_bitwidth(_insn->reg_elwidth(reg, true), xlen);
int shift = 0;
+ int offs = 0;
if (spec.offset && spec.reg != 2) { // XXX HACK on spec.reg != 2
- int offs = *spec.offset;
int nbytes = xlen / bitwidth;
+ offs = *spec.offset;
shift = offs % nbytes;
offs /= nbytes;
- reg += *spec.offset;
+ reg += offs;
}
uint64_t data = _insn->p->get_state()->XPR[reg];
+ uint64_t ndata = data;
if (xlen != bitwidth)
{
- data = data >> (shift*8); // gets the right element within the reg-block
- data &= ((1<<bitwidth)-1); // masks off the right bits
+ ndata = data >> (shift*bitwidth); // gets element within the reg-block
+ ndata &= ((1UL<<bitwidth)-1UL); // masks off the right bits
+ fprintf(stderr, "readreg %d bitwidth %d offs %d shift %d %lx->%lx\n",
+ spec.reg, bitwidth, offs, shift, data, ndata);
}
- return data;
+ return ndata;
}
sv_reg_t sv_proc_t::get_intreg(reg_spec_t const&spec)