start modifying DO_WRITE_FREG to store elwidth-based fp
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 30 Oct 2018 09:44:40 +0000 (09:44 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 30 Oct 2018 09:44:40 +0000 (09:44 +0000)
riscv/sv_insn_redirect.cc

index d02fcb0bf23f7c19c1be4419e3c016bd98009e5d..f635d298d91bc9e243602cc7bba13b5ef4d3410f 100644 (file)
@@ -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<<bitwidth)-1UL) << (shift*bitwidth);
         wval = (uint64_t)(wval << (shift*bitwidth)); // element within reg-block
@@ -96,10 +124,10 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value)
         } else {
             if (_insn->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);
 }