alter operation width based on max bitwidth, and sign/zero-extend
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 26 Oct 2018 03:09:43 +0000 (04:09 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 26 Oct 2018 03:09:43 +0000 (04:09 +0100)
riscv/sv_insn_redirect.cc

index 62aaaf9345a9b9cb3705c326b51dfaaca63bcbae..d98f0d8a8ed2e1377b96d45db29565415bc2ac06 100644 (file)
@@ -114,7 +114,7 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value)
         wval = wval << (shift*bitwidth); // gets element within the reg-block
         uint64_t ndata = data & (uint64_t)(~mask); // masks off the right bits
         wval |= ndata;
-        fprintf(stderr, "writereg %d bitwidth %d offs %d shift %d %lx " \
+        fprintf(stderr, "writereg %lx bitwidth %d offs %d shift %d %lx " \
                         " %lx %lx %lx\n",
                         spec.reg, bitwidth, offs, shift, data,
                         ndata, mask, wval);
@@ -151,7 +151,7 @@ reg_t (sv_proc_t::READ_REG)(reg_spec_t const& spec)
     {
         ndata = data >> (shift*bitwidth); // gets element within the reg-block
         ndata &= ((1UL<<bitwidth)-1UL); // masks off the right bits
-        fprintf(stderr, "readreg %d bitwidth %d offs %d shift %d %lx->%lx\n",
+        fprintf(stderr, "readreg %lx bitwidth %d offs %d shift %d %lx->%lx\n",
                         spec.reg, bitwidth, offs, shift, data, ndata);
     }
     return ndata;
@@ -342,7 +342,21 @@ sv_reg_t::operator sv_reg_t ()
 sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs)
 {
     uint8_t bitwidth = _insn->src_bitwidth;
-    return lhs + rhs;
+    if (bitwidth == xlen) {
+        return lhs + rhs;
+    }
+    uint64_t vlhs = 0;
+    uint64_t vrhs = 0;
+    // sign-extend or zero-extend to max bitwidth of lhs and rhs?
+    // has the effect of truncating, as well.
+    if (_insn->signextended) { // sign-extend?
+        vlhs = sext_bwid(lhs, bitwidth);
+        vrhs = sext_bwid(rhs, bitwidth);
+    } else { // nope: zero-extend.
+        vlhs = zext_bwid(lhs, bitwidth);
+        vrhs = zext_bwid(rhs, bitwidth);
+    }
+    return sv_reg_t(vlhs + vrhs, xlen); // XXX TODO: bitwidth
 }
 
 sv_reg_t sv_proc_t::rv_sub(sv_reg_t const & lhs, sv_reg_t const & rhs)