expand register size to 128 long, add exceptions if bounds exceeded
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Nov 2018 11:26:44 +0000 (11:26 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Nov 2018 11:26:44 +0000 (11:26 +0000)
also adding debug prints for tracking down obscure fmv bug

riscv/decode.h
riscv/processor.h
riscv/sv_insn_redirect.cc

index 40da8a17f579f7da8ba3bf525ecb7c9803989327..8aa6411b4c2eaacfa49c3793f97cca8df1dcb459 100644 (file)
@@ -26,6 +26,10 @@ typedef uint64_t reg_t;
 
 const int NXPR = 32;
 const int NFPR = 32;
+#ifdef SPIKE_SIMPLEV
+const int SV_NXPR = NXPR*4;
+const int SV_NFPR = NFPR*4;
+#endif
 const int NCSR = 4096;
 
 #define X_RA 1
index 22e9d855aec384002751375cfab45eddd8bfb5e2..93fa39c5b0a2a7518d9e22bca557bfb557ab79c0 100644 (file)
@@ -97,8 +97,8 @@ struct state_t
 
   reg_t pc;
 #ifdef SPIKE_SV
-  regfile_t<reg_t, NXPR*4, true> XPR;
-  regfile_t<freg_t, NFPR*4, false> FPR;
+  regfile_t<reg_t, SV_NXPR, true> XPR;
+  regfile_t<freg_t, SV_NFPR, false> FPR;
 #else
   regfile_t<reg_t, NXPR, true> XPR;
   regfile_t<freg_t, NFPR, false> FPR;
index 47ae9c93c432bbdb9f89813ffe26371f6d1776e9..6d4de6714e8afbe3ff983519dd20c1d8e2f99184 100644 (file)
@@ -19,6 +19,7 @@ void (sv_proc_t::WRITE_FRD)(sv_float32_t value)
         case 2:
         {
             float16_t x16 = ::f32_to_f16((float32_t)value);
+            fprintf(stderr, "f32-to-f16\n");
             v = freg(x16);
             break;
         }
@@ -137,6 +138,9 @@ void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value)
         fprintf(stderr, "writefreg spec %ld bitwidth %d offs %d shift %d\n",
                         reg, bitwidth, offs, shift);
     }
+    if (((int)reg) >= SV_NFPR) {
+        throw trap_illegal_instruction(0);
+    }
     freg_shift fd;
     if (xlen != bitwidth)
     {
@@ -186,6 +190,9 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value)
         fprintf(stderr, "writereg spec %ld %lx bitwidth %d offs %d shift %d\n",
                         reg, wval, bitwidth, offs, shift);
     }
+    if (((int)reg) >= SV_NFPR) {
+        throw trap_illegal_instruction(0);
+    }
     if (xlen != bitwidth)
     {
         char report[2] = {};
@@ -216,7 +223,7 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value)
 
 freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec)
 {
-    //int flen = sizeof(freg_t) * 8; // FLEN (not specified in spike)
+    int regflen = sizeof(freg_t) * 8; // FLEN (not specified in spike)
     int flen = _insn->flen;
     reg_t reg = spec.reg;
     uint8_t elwidth = _insn->reg_elwidth(reg, false);
@@ -233,16 +240,19 @@ freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec)
         offs /= nbytes;
         reg += offs;
     }
+    if (((int)reg) >= SV_NFPR) {
+        throw trap_illegal_instruction(0);
+    }
     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)
+    if (regflen != bitwidth)
     {
         // shuffle the data down by bytes (annoying but easier)
         int sblen = shift*bitwidth/8;
-        for (int i = 0; i < ((int)flen/8); i++) {
+        for (int i = 0; i < ((int)regflen/8); i++) {
             if (i < (bitwidth/8)) {
                fs.b[i] = fs.b[i+sblen];
             } else {
@@ -274,6 +284,9 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec,
         offs /= nbytes;
         reg += offs;
     }
+    if (((int)reg) >= SV_NFPR) {
+        throw trap_illegal_instruction(0);
+    }
     uint64_t data = _insn->p->get_state()->XPR[reg];
     uint64_t ndata = data;
     if (addr_mode)
@@ -554,6 +567,7 @@ sv_reg_t sv_proc_t::sv_reg_uint32(sv_reg_t const& v)
 
 sv_float32_t (sv_proc_t::f32)(sv_freg_t x)
 {
+    freg_t v = (freg_t)x;
     switch (x.get_elwidth())
     {
         // 8-bit
@@ -566,15 +580,21 @@ sv_float32_t (sv_proc_t::f32)(sv_freg_t x)
             fprintf(stderr, "f16-to-f32 %lx\n", (uint64_t)x32);
             return f16_to_f32(f_16);
         }
-        // 0 and 3 are 32-bit
+        case 3:
+        {
+            return sv_float32_t(::f32(x.to_uint32()));
+        }
         default: break;
     }
-    return ::f32(x);
+    sv_float32_t value = ::f32(v);
+    fprintf(stderr, "::f32 %lx %lx %x\n", v.v[0], v.v[1], ((float32_t)value).v);
+    return value;
 }
 
 sv_float32_t (sv_proc_t::f32)(sv_reg_t const& v)
 {
     uint64_t x = v;
+    fprintf(stderr, "::f32 %lx\n", x);
     switch (v.get_elwidth())
     {
         // 8-bit
@@ -913,9 +933,14 @@ 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 )
 {
+    reg_t reg = _insn->rd().reg;
+    uint8_t dest_elwidth = _insn->reg_elwidth(reg, false);
     //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);
+    sv_float32_t value = ::f32_add(a, b);
+    fprintf(stderr, "f32_add a %x b %x sv_float32_t %x\n",
+            ((float32_t)a).v, ((float32_t)b).v, ((float32_t)value).v);
+    return value;
 }
 
 sv_float32_t (sv_proc_t::f32_sub)( sv_float32_t a, sv_float32_t b )