STATE.XPR.write(reg, wval);
}
+union freg_shift {
+ freg_t f;
+ uint8_t b[sizeof(freg_t)*8];
+};
+
freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec)
{
+ int flen = sizeof(freg_t) * 8; // FLEN (not specified in spike)
reg_t reg = spec.reg;
- uint8_t elwidth = _insn->reg_elwidth(reg, true);
- if (spec.offset) {
- reg += *spec.offset;
+ uint8_t elwidth = _insn->reg_elwidth(reg, false);
+ int bitwidth = get_bitwidth(elwidth, flen);
+ int shift = 0;
+ int offs = 0;
+ if (spec.offset != NULL) {
+ int nbytes = flen / bitwidth;
+ if (nbytes == 0) {
+ nbytes = 1;
+ }
+ offs = *spec.offset;
+ shift = offs % nbytes;
+ offs /= nbytes;
+ reg += offs;
+ }
+ freg_shift fs;
+ fs.f = _insn->p->get_state()->FPR[reg];
+ fprintf(stderr, "READ_FREG rd %ld ew %d bw %d fl %d data %lx %lx\n",
+ reg, elwidth, bitwidth, flen, fs.f.v[0], fs.f.v[1]);
+
+ if (flen != bitwidth)
+ {
+ // shuffle the data down by bytes (annoying but easier)
+ int sblen = shift*bitwidth/8;
+ for (int i = 0; i < ((int)flen/8); i++) {
+ if (i < (bitwidth/8)) {
+ fs.b[i] = fs.b[i+sblen];
+ } else {
+ fs.b[i] = 0xff;
+ }
+ }
+ fprintf(stderr, "readfreg %ld bitwidth %d offs %d " \
+ "shift %d %lx:%lx\n",
+ spec.reg, bitwidth, offs, shift,
+ fs.f.v[0], fs.f.v[1]);
}
- freg_t value = _insn->p->get_state()->FPR[reg];
- fprintf(stderr, "READ_FREG rd %ld ew %d data %lx %lx\n",
- reg, elwidth, ((freg_t)value).v[0], ((freg_t)value).v[1]);
- return value;
+ return fs.f;
}
reg_t sv_proc_t::READ_REG(reg_spec_t const& spec,