From bcf96d8894aed064ec1ed97d1ceb09d6c84440f2 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 31 Oct 2018 00:21:51 +0000 Subject: [PATCH] add 32-fp16 load/convert in WRITE_FRD --- riscv/decode.h | 1 + riscv/sv_insn_redirect.cc | 68 ++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index bc0bd79..40da8a1 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -248,6 +248,7 @@ inline float16_t f16(freg_t r) { return f16(unboxF16(r)); } inline float32_t f32(freg_t r) { return f32(unboxF32(r)); } inline float64_t f64(freg_t r) { return f64(unboxF64(r)); } inline float128_t f128(freg_t r) { return r; } +inline freg_t freg(float16_t f) { return { ((uint64_t)-1 << 16) | f.v, (uint64_t)-1 }; } inline freg_t freg(float32_t f) { return { ((uint64_t)-1 << 32) | f.v, (uint64_t)-1 }; } inline freg_t freg(float64_t f) { return { f.v, (uint64_t)-1 }; } inline freg_t freg(float128_t f) { return f; } diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index f635d29..9d903d5 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -6,10 +6,37 @@ void (sv_proc_t::WRITE_FRD)(sv_float32_t value) { - fprintf(stderr, "WRITE_FRD sv_float32_t %lx\n", - ((float32_t)value).v); - sv_freg_t v = sv_freg_t(freg(value), xlen, value.get_elwidth()); - DO_WRITE_FREG( _insn->rd(), v); + reg_t reg = _insn->rd().reg; + uint8_t dest_elwidth = _insn->reg_elwidth(reg, false); + fprintf(stderr, "WRITE_FRD rd %ld ew %d sv_float32_t %x\n", + reg, dest_elwidth, ((float32_t)value).v); + freg_t v; + 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 = ::f32_to_f16((float32_t)value); + v = freg(x16); + break; + } + case 3: + { + v = freg(value); + //float32_t x32 = ::f128_to_f32((float32_t)value); + //v = ::f32_to_f128(x32); + break; + } + default: + { + v = freg(value); + break; + } + } + sv_freg_t vf = sv_freg_t(v, xlen, value.get_elwidth()); + DO_WRITE_FREG( _insn->rd(), vf); } void (sv_proc_t::WRITE_FRD)(sv_float64_t value) @@ -66,31 +93,9 @@ void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value) if (spec.offset) { reg += *spec.offset; } - 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); + fprintf(stderr, "DO_WRITE_FRD rd %ld ew %d data %lx %lx\n", + reg, dest_elwidth, ((freg_t)value).v[0], ((freg_t)value).v[1]); + STATE.FPR.write(reg, value); dirty_fp_state; } @@ -145,7 +150,10 @@ freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec) if (spec.offset) { reg += *spec.offset; } - return _insn->p->get_state()->FPR[reg]; // XXX TODO: offset + 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; } reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, -- 2.30.2