return _insn->p->get_state()->FPR[reg]; // XXX TODO: offset
}
-reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, sv_reg_t const& imm,
+reg_t sv_proc_t::READ_REG(reg_spec_t const& spec,
bool addr_mode, size_t width)
{
reg_t reg = spec.reg;
reg += offs;
}
uint64_t data = _insn->p->get_state()->XPR[reg];
- uint64_t ndata = data; // + (int64_t)imm;
- if (((uint64_t)xlen) != ((uint64_t)bitwidth))
+ uint64_t ndata = data;
+ if (addr_mode)
{
- ndata = data >> (shift*bitwidth); // gets element within the reg-block
- ndata &= ((1UL<<bitwidth)-1UL); // masks off the right bits
- fprintf(stderr, "readreg %ld bitwidth %d offs %d shift %d %lx->%lx\n",
+ // offset data to load by the number of BYTES not bits
+ ndata = data + (bitwidth * shift / 8);
+ fprintf(stderr, "readreg ADDRmode %ld bitwidth %d offs %d " \
+ "shift %d %lx->%lx\n",
spec.reg, bitwidth, offs, shift, data, ndata);
}
+ else
+ {
+ if (((uint64_t)xlen) != ((uint64_t)bitwidth))
+ {
+ // gets element within the reg-block
+ ndata = data >> (shift*bitwidth);
+ ndata &= ((1UL<<bitwidth)-1UL); // masks off the right bits
+ fprintf(stderr, "readreg %ld bitwidth %d offs %d " \
+ "shift %d %lx->%lx\n",
+ spec.reg, bitwidth, offs, shift, data, ndata);
+ }
+ }
return ndata;
}
sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs,
size_t width, bool ext)
{
- // okaay, so a different "mode" applies, here
- reg_t reg = READ_REG(spec, true, offs, width);
+ // okaay, so a different "mode" applies, here: addr_mode.
+ // addr_mode doesn't truncate the register to elwidth-specified
+ // bitsize, it adds a modulo-offset based on the current VL loop index
+ reg_t reg = READ_REG(spec, true, width);
sv_reg_t addr = rv_add(reg, offs);
+
+ // now that the address has been moved on by the modulo-offset,
+ // get only an elwidth-sized element (if not "default")
+ width = get_bitwidth(_insn->reg_elwidth(spec.reg, true), width);
switch (width)
{
case 8:
else return p->get_mmu()->load_int64(addr);
break;
}
- return 0;
+ return 0; // XXX should never get here!
}
sv_reg_t sv_proc_t::adjust_load(sv_reg_t const& v, size_t width, bool ext)
void (WRITE_FRD)(sv_float128_t value);
void (WRITE_FRD)(sv_float64_t value);
void (WRITE_FRD)(sv_float32_t value);
- reg_t READ_REG(reg_spec_t const& i, sv_reg_t const& imm,
- bool addr_mode, size_t width);
+ reg_t READ_REG(reg_spec_t const& i, bool addr_mode, size_t width);
reg_t READ_REG(reg_spec_t const& spec)
- { return READ_REG(spec, sv_reg_t(0), false, xlen); }
+ { return READ_REG(spec, false, xlen); }
freg_t (READ_FREG)(reg_spec_t const& i);
processor_t *p;