break int op down into prepare, do, and finish
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 6 Nov 2018 11:18:43 +0000 (11:18 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 6 Nov 2018 11:18:43 +0000 (11:18 +0000)
riscv/sv_insn_redirect.cc
riscv/sv_insn_redirect.h

index 0664f58ed5a34f5d08a1b9da632a6ce87c42c5c3..12ae22005e87cac41e18030fb673825f3c672751 100644 (file)
@@ -130,7 +130,7 @@ unsigned int sv_proc_t::remap(reg_spec_t const& spec)
     // the map is still calculated even for the 1D case
     // because it's a linear map
     unsigned int res = (unsigned int)shape->map[offs] + shape->offs;
-    fprintf(stderr, "remap %d %d -> %d\n",
+    fprintf(stderr, "remap %ld %d -> %d\n",
                     spec.reg, offs, res);
     return res;
 }
@@ -429,17 +429,14 @@ sv_reg_t (sv_proc_t::zext32)(sv_reg_t const& v)
     return sv_reg_t(x);
 }
 
-sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs)
+bool sv_proc_t::rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs,
+                                 uint64_t &vlhs, uint64_t &vrhs,
+                                 uint8_t &bitwidth)
 {
-    uint8_t bitwidth = _insn->src_bitwidth;
+    bitwidth = _insn->src_bitwidth;
     if (bitwidth == xlen) {
-        fprintf(stderr, "add result %lx %lx %lx\n",
-                (uint64_t)lhs, (uint64_t)rhs, (uint64_t)(lhs + rhs));
-        return lhs + rhs;
+        return true;
     }
-    uint64_t vlhs = 0;
-    uint64_t vrhs = 0;
-    uint64_t result = 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?
@@ -449,21 +446,47 @@ sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs)
         vlhs = zext_bwid(lhs, bitwidth);
         vrhs = zext_bwid(rhs, bitwidth);
     }
-    result = vlhs + vrhs;
+    return false;
+}
+
+sv_reg_t sv_proc_t::rv_int_op_finish(sv_reg_t const & lhs, sv_reg_t const & rhs,
+                                 uint64_t &result, uint8_t &bitwidth)
+{
     if (_insn->signextended) { // sign-extend?
         result = sext_bwid(result, bitwidth);
     } else { // nope: zero-extend.
         result = zext_bwid(result, bitwidth);
     }
     uint8_t reswidth = maxelwidth(lhs.get_elwidth(), rhs.get_elwidth());
-    fprintf(stderr, "add result sext %d wid %d %lx\n", _insn->signextended,
+    fprintf(stderr, "result sext %d wid %d %lx\n", _insn->signextended,
                                                         reswidth, result);
-    return sv_reg_t(result, xlen, reswidth); // XXX TODO: bitwidth
+    return sv_reg_t(result, xlen, reswidth);
+}
+
+sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs)
+{
+    uint8_t bitwidth = _insn->src_bitwidth;
+    uint64_t vlhs = 0;
+    uint64_t vrhs = 0;
+    if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth)) {
+        fprintf(stderr, "add result %lx %lx %lx\n",
+                (uint64_t)lhs, (uint64_t)rhs, (uint64_t)(lhs + rhs));
+        return lhs + rhs;
+    }
+    uint64_t result = vlhs + vrhs;
+    return rv_int_op_finish(lhs, rhs, result, bitwidth);
 }
 
 sv_reg_t sv_proc_t::rv_sub(sv_reg_t const & lhs, sv_reg_t const & rhs)
 {
-    return lhs - rhs;
+    uint8_t bitwidth = _insn->src_bitwidth;
+    uint64_t vlhs = 0;
+    uint64_t vrhs = 0;
+    if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth)) {
+        return lhs - rhs;
+    }
+    uint64_t result = vlhs - vrhs;
+    return rv_int_op_finish(lhs, rhs, result, bitwidth);
 }
 
 sv_sreg_t sv_proc_t::rv_div(sv_sreg_t const & lhs, sv_sreg_t const & rhs)
index 9f77b17f09b49ca755d82699155a61df64a712f0..5f6bf6fb71c5535b3f61534ec709d3daaa95bcc9 100644 (file)
@@ -262,6 +262,12 @@ public:
 
     unsigned int remap(reg_spec_t const& regspec);
 
+    bool rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs,
+                           uint64_t &vlhs, uint64_t &vrhs,
+                           uint8_t &bitwidth);
+    sv_reg_t rv_int_op_finish(sv_reg_t const & lhs, sv_reg_t const & rhs,
+                                 uint64_t &result, uint8_t &bitwidth);
+
 #include "sv_insn_decl.h"
 };