break register down in non-default elwidth case
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 25 Oct 2018 09:10:50 +0000 (10:10 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 25 Oct 2018 09:10:50 +0000 (10:10 +0100)
riscv/sv_insn_redirect.cc

index e674ab75cba5d60708a7c09b5e07b30679a52050..5298bc1087e8e9c9ffc5c25de70cb0029556fc46 100644 (file)
@@ -115,11 +115,22 @@ freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec)
 reg_t (sv_proc_t::READ_REG)(reg_spec_t const& spec)
 {
     reg_t reg = spec.reg;
-    uint8_t elwidth = _insn->reg_elwidth(reg, true);
+    int bitwidth = get_bitwidth(_insn->reg_elwidth(reg, true), xlen);
+    int shift = 0;
     if (spec.offset && spec.reg != 2) { // XXX HACK on spec.reg != 2
+        int offs = *spec.offset;
+        int nbytes = xlen / bitwidth;
+        shift = offs % nbytes;
+        offs /= nbytes;
         reg += *spec.offset;
     }
-    return _insn->p->get_state()->XPR[reg]; // XXX TODO: offset
+    uint64_t data = _insn->p->get_state()->XPR[reg];
+    if (xlen != bitwidth)
+    {
+        data = data >> (shift*8); // gets the right element within the reg-block
+        data &= ((1<<bitwidth)-1); // masks off the right bits
+    }
+    return data;
 }
 
 sv_reg_t sv_proc_t::get_intreg(reg_spec_t const&spec)