add element-offset mode on LD/ST when isvec=false on address
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 17 Nov 2018 05:35:37 +0000 (05:35 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 17 Nov 2018 05:35:37 +0000 (05:35 +0000)
riscv/sv.cc
riscv/sv_insn_redirect.cc

index 016fbd8689f5eabad9a175d65ae1ff004e9725f5..25f9e545c7235cb487595174639dfe553946d673 100644 (file)
@@ -119,10 +119,14 @@ bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg)
   }
   if (r->active && r->isvec)
   {
-    fprintf(stderr, "checkreg: %ld active\n", reg);
+    fprintf(stderr, "checkreg: %ld active isvec\n", reg);
     at_least_one_reg_vectorised = true;
     return true;
   }
+  if (r->active)
+  {
+    fprintf(stderr, "checkreg: %ld active !vec\n", reg);
+  }
   return false;
 }
 
@@ -167,10 +171,12 @@ reg_spec_t sv_insn_t::remap(uint64_t reg, bool intreg, int *voffs)
 
   // now we determine if this is a scalar/vector: if it's scalar
   // we return the re-mapped register...
+#if 0
   if (!r->isvec) // scalar
   {
     return spec;
   }
+#endif
   vloop_continue = true;
 
   // aaand now, as it's a "vector", FINALLY we can pass the loop-offset
index 640d87460b2d4639ef201280a626ae09e21e5321..5744f03ddaa690bd1f28867b628c065e32825b7e 100644 (file)
@@ -166,7 +166,9 @@ void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value)
         offs = remap(spec);
         shift = offs % nbytes;
         offs /= nbytes;
-        reg += offs;
+        if (spec.isvec) {
+            reg += offs;
+        }
         fprintf(stderr, "writefreg spec %ld bitwidth %d offs %d shift %d\n",
                         reg, bitwidth, offs, shift);
     }
@@ -218,7 +220,9 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value)
         offs = remap(spec);
         shift = offs % nbytes;
         offs /= nbytes;
-        reg += offs;
+        if (spec.isvec) {
+            reg += offs;
+        }
         fprintf(stderr, "writereg spec %ld %lx bitwidth %d offs %d shift %d\n",
                         reg, wval, bitwidth, offs, shift);
     }
@@ -278,7 +282,9 @@ freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec)
         offs = remap(spec);
         shift = offs % nbytes;
         offs /= nbytes;
-        reg += offs;
+        if (spec.isvec) {
+            reg += offs;
+        }
     }
     if (((int)reg) >= SV_NFPR) {
         throw trap_illegal_instruction(0);
@@ -313,16 +319,19 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec,
     reg_t reg = spec.reg;
     int bitwidth = get_bitwidth(_insn->reg_elwidth(reg, true), xlen);
     int shift = 0;
+    int origoffs = 0;
     int offs = 0;
     if (spec.offset != NULL) {
         int nbytes = width / bitwidth;
         if (nbytes == 0) {
             nbytes = 1;
         }
-        offs = remap(spec);
-        shift = offs % nbytes;
-        offs /= nbytes;
-        reg += offs;
+        origoffs = remap(spec);
+        shift = origoffs % nbytes;
+        offs  = origoffs / nbytes;
+        if (spec.isvec) {
+            reg += offs;
+        }
     }
     if (((int)reg) >= SV_NFPR) {
         throw trap_illegal_instruction(0);
@@ -332,10 +341,15 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec,
     if (addr_mode)
     {
         // offset data to load by the number of BYTES not bits
-        ndata = data + (bitwidth * shift / 8);
-        fprintf(stderr, "readreg ADDRmode %ld %ld bitwidth %d offs %d " \
+        if (spec.isvec) {
+            ndata = data + (bitwidth * shift / 8);
+        } else {
+            ndata = data + (bitwidth * origoffs / 8);
+        }
+        fprintf(stderr, "readreg ADDRmode %p %ld %ld bw %d offs (%d) %d " \
                         "shift %d %lx->%lx\n",
-                        spec.reg, reg, bitwidth, offs, shift, data, ndata);
+                        spec.offset, spec.reg, reg, bitwidth,
+                        origoffs, offs, shift, data, ndata);
     }
     else
     {
@@ -1191,15 +1205,19 @@ sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs,
     // addr_mode doesn't truncate the register to elwidth-specified
     // bitsize, it adds a modulo-offset based on the current VL loop index
     reg_t reg = READ_REG(spec, true, width);
-    sv_reg_t addr = sv_reg_t((uint64_t)reg + (int64_t)offs);
+    uint64_t regoffs = 0;
+    //if (spec.offset && !spec.isvec) {
+    //    regoffs = *spec.offset;
+    //}
+    sv_reg_t addr = sv_reg_t((uint64_t)reg + (uint64_t)regoffs + (int64_t)offs);
     sv_reg_t v(0);
 
     // now that the address has been moved on by the modulo-offset,
     // get only an elwidth-sized element (if not "default")
     uint8_t rwidth = _insn->reg_elwidth(spec.reg, true);
     width = get_bitwidth(rwidth, width);
-    fprintf(stderr, "mmu_load wid %ld addr %lx offs %lx\n",
-                    width, (uint64_t)reg, (int64_t)offs);
+    fprintf(stderr, "mmu_load wid %ld reg %lx regoffs %lx offs %lx\n",
+                    width, (uint64_t)reg, regoffs, (int64_t)offs);
     switch (width)
     {
         case 8:
@@ -1219,7 +1237,7 @@ sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs,
             else     v = p->get_mmu()->load_int64(addr);
             break;
     }
-    fprintf(stderr, "mmu_load wid %ld addr %lx offs %lx loaded %lx\n",
+    fprintf(stderr, "mmu_load wid %ld reg %lx offs %lx loaded %lx\n",
                     width, (uint64_t)reg, (int64_t)offs, (uint64_t)v);
     v.set_elwidth(rwidth);
     v.set_xlen(xlen);