add 32-fp16 load/convert in WRITE_FRD
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Oct 2018 00:21:51 +0000 (00:21 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 31 Oct 2018 00:21:51 +0000 (00:21 +0000)
riscv/decode.h
riscv/sv_insn_redirect.cc

index bc0bd79e9e8fe7da1edf5c33f94300d1223b96dc..40da8a17f579f7da8ba3bf525ecb7c9803989327 100644 (file)
@@ -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; }
index f635d298d91bc9e243602cc7bba13b5ef4d3410f..9d903d5c341656f5602d0b2a20e3dec59bb2b87d 100644 (file)
@@ -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,