From fb8f7d3d3e8f0c6ced6aef3010bf409263314cdb Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 31 Oct 2018 07:47:05 +0000 Subject: [PATCH] READ_FREG reads fp16 from offset into reg array --- riscv/sv_insn_redirect.cc | 48 +++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 06a154f..a11ec6a 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -143,17 +143,51 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value) 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, -- 2.30.2