add in addrmode
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 29 Oct 2018 02:17:10 +0000 (02:17 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 29 Oct 2018 02:17:10 +0000 (02:17 +0000)
riscv/sv_insn_redirect.cc
riscv/sv_insn_redirect.h

index 1e2c542c13c6abf29ae8d915e7d712c63aad5e48..7f6aded620fbd7e5ec86b3a5e95d7299b75f6628 100644 (file)
@@ -145,7 +145,7 @@ freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec)
     return _insn->p->get_state()->FPR[reg]; // XXX TODO: offset
 }
 
-reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, sv_reg_t const& imm,
+reg_t sv_proc_t::READ_REG(reg_spec_t const& spec,
                          bool addr_mode, size_t width)
 {
     reg_t reg = spec.reg;
@@ -163,14 +163,27 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, sv_reg_t const& imm,
         reg += offs;
     }
     uint64_t data = _insn->p->get_state()->XPR[reg];
-    uint64_t ndata = data; // + (int64_t)imm;
-    if (((uint64_t)xlen) != ((uint64_t)bitwidth))
+    uint64_t ndata = data;
+    if (addr_mode)
     {
-        ndata = data >> (shift*bitwidth); // gets element within the reg-block
-        ndata &= ((1UL<<bitwidth)-1UL); // masks off the right bits
-        fprintf(stderr, "readreg %ld bitwidth %d offs %d shift %d %lx->%lx\n",
+        // offset data to load by the number of BYTES not bits
+        ndata = data + (bitwidth * shift / 8);
+        fprintf(stderr, "readreg ADDRmode %ld bitwidth %d offs %d " \
+                        "shift %d %lx->%lx\n",
                         spec.reg, bitwidth, offs, shift, data, ndata);
     }
+    else
+    {
+        if (((uint64_t)xlen) != ((uint64_t)bitwidth))
+        {
+            // gets element within the reg-block
+            ndata = data >> (shift*bitwidth);
+            ndata &= ((1UL<<bitwidth)-1UL); // masks off the right bits
+            fprintf(stderr, "readreg %ld bitwidth %d offs %d " \
+                            "shift %d %lx->%lx\n",
+                            spec.reg, bitwidth, offs, shift, data, ndata);
+        }
+    }
     return ndata;
 }
 
@@ -933,9 +946,15 @@ sv_float128_t sv_proc_t::f64_to_f128( sv_float64_t a)
 sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs,
                                 size_t width, bool ext)
 {
-    // okaay, so a different "mode" applies, here
-    reg_t reg = READ_REG(spec, true, offs, width);
+    // okaay, so a different "mode" applies, here: addr_mode.
+    // 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 = rv_add(reg, offs);
+
+    // now that the address has been moved on by the modulo-offset,
+    // get only an elwidth-sized element (if not "default")
+    width = get_bitwidth(_insn->reg_elwidth(spec.reg, true), width);
     switch (width)
     {
         case 8:
@@ -954,7 +973,7 @@ sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs,
             else     return p->get_mmu()->load_int64(addr);
             break;
     }
-    return 0;
+    return 0; // XXX should never get here!
 }
 
 sv_reg_t sv_proc_t::adjust_load(sv_reg_t const& v, size_t width, bool ext)
index 4cd2bb2ba1301434128485e1343ad8a196b872d4..a1094e3baa5abc59780a29226e3a0ee299fc223c 100644 (file)
@@ -85,10 +85,9 @@ public:
     void (WRITE_FRD)(sv_float128_t value);
     void (WRITE_FRD)(sv_float64_t value);
     void (WRITE_FRD)(sv_float32_t value);
-    reg_t READ_REG(reg_spec_t const& i, sv_reg_t const& imm,
-                     bool addr_mode, size_t width);
+    reg_t READ_REG(reg_spec_t const& i, bool addr_mode, size_t width);
     reg_t READ_REG(reg_spec_t const& spec)
-    { return READ_REG(spec, sv_reg_t(0), false,  xlen); }
+            { return READ_REG(spec, false,  xlen); }
     freg_t (READ_FREG)(reg_spec_t const& i);
 
     processor_t *p;