From: Luke Kenneth Casson Leighton Date: Tue, 30 Oct 2018 09:44:40 +0000 (+0000) Subject: start modifying DO_WRITE_FREG to store elwidth-based fp X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f29274c76f04b743119a47330d82d5fbb3504de3;p=riscv-isa-sim.git start modifying DO_WRITE_FREG to store elwidth-based fp --- diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index d02fcb0..f635d29 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -8,21 +8,24 @@ void (sv_proc_t::WRITE_FRD)(sv_float32_t value) { fprintf(stderr, "WRITE_FRD sv_float32_t %lx\n", ((float32_t)value).v); - DO_WRITE_FREG( _insn->rd(), freg(value) ); + sv_freg_t v = sv_freg_t(freg(value), xlen, value.get_elwidth()); + DO_WRITE_FREG( _insn->rd(), v); } void (sv_proc_t::WRITE_FRD)(sv_float64_t value) { fprintf(stderr, "WRITE_FRD sv_float64_t %g\n", (double)((float64_t)value).v); - DO_WRITE_FREG( _insn->rd(), freg(value) ); + sv_freg_t v = sv_freg_t(freg(value), xlen, value.get_elwidth()); + DO_WRITE_FREG( _insn->rd(), v ); } void (sv_proc_t::WRITE_FRD)(sv_float128_t value) { fprintf(stderr, "WRITE_FRD sv_float128_t %g\n", (double)((float128_t)value).v[0]); - DO_WRITE_FREG( _insn->rd(), freg(((float128_t)value)) ); + sv_freg_t v = sv_freg_t(freg(((float128_t)value)), xlen, value.get_elwidth()); + DO_WRITE_FREG( _insn->rd(), v ); } void (sv_proc_t::WRITE_FRD)(sv_freg_t value) @@ -59,10 +62,35 @@ void (sv_proc_t::WRITE_RD)(sv_reg_t const& value) void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value) { reg_t reg = spec.reg; + uint8_t dest_elwidth = _insn->reg_elwidth(reg, false); if (spec.offset) { reg += *spec.offset; } - STATE.FPR.write(reg, value); + sv_freg_t v(value); + switch (dest_elwidth) + { + // 8-bit + case 1: throw trap_illegal_instruction(0); // XXX for now + // 16-bit data, up-convert to f32 + case 2: + { + float16_t x16 = ::f128_to_f16((freg_t)value); + v = sv_freg_t(::f16_to_f128(x16)); + break; + } + case 3: + { + float32_t x32 = ::f128_to_f32((freg_t)value); + v = sv_freg_t(::f32_to_f128(x32)); + break; + } + default: + { + v = value; + break; + } + } + STATE.FPR.write(reg, v); dirty_fp_state; } @@ -84,7 +112,7 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value) } if (xlen != bitwidth) { - char *report = ""; + char report[2] = {}; uint64_t data = _insn->p->get_state()->XPR[reg]; uint64_t mask = ((1UL<signextended) { wval = sext_bwid(wval, bitwidth); - report = "s"; + report[0] = 's'; } else { wval = zext_bwid(wval, bitwidth); - report = "z"; + report[0] = 'z'; } } fprintf(stderr, "writereg %s %ld bitwidth %d offs %d shift %d %lx " \ @@ -697,6 +725,8 @@ bool (sv_proc_t::f64_lt_quiet)( sv_float64_t a, sv_float64_t b ) sv_float32_t (sv_proc_t::f32_add)( sv_float32_t a, sv_float32_t b ) { + //uint8_t reswidth = maxelwidth(a.get_elwidth(), b.get_elwidth()); + //return sv_float32_t(::f32_add(a, b), xlen, reswidth); return ::f32_add(a, b); }