add unsigned versions of rv_int_op_prepare and finish
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 6 Nov 2018 17:45:15 +0000 (17:45 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 6 Nov 2018 17:45:15 +0000 (17:45 +0000)
riscv/sv_insn_redirect.cc
riscv/sv_insn_redirect.h

index c7872bcb9a9598d884cf913ca79066d5e643c8c0..7df63fc3d4cd68642afde9facf41acb49362b556 100644 (file)
@@ -449,6 +449,41 @@ bool sv_proc_t::rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs,
     return false;
 }
 
+bool sv_proc_t::rv_int_op_prepare(sv_sreg_t const & lhs, sv_sreg_t const & rhs,
+                                 int64_t &vlhs, int64_t &vrhs,
+                                 uint8_t &bitwidth)
+{
+    bitwidth = _insn->src_bitwidth;
+    if (bitwidth == xlen) {
+        return true;
+    }
+    // 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 false;
+}
+
+sv_sreg_t sv_proc_t::rv_int_op_finish(sv_sreg_t const & lhs,
+                                      sv_sreg_t const & rhs,
+                                 int64_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, "result sext %d wid %d %lx\n", _insn->signextended,
+                                                        reswidth, result);
+    return sv_reg_t(result, xlen, reswidth);
+}
+
 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)
 {
@@ -491,7 +526,17 @@ sv_reg_t sv_proc_t::rv_sub(sv_reg_t const & lhs, sv_reg_t const & rhs)
 
 sv_sreg_t sv_proc_t::rv_div(sv_sreg_t const & lhs, sv_sreg_t const & rhs)
 {
-    return lhs / rhs;
+    uint8_t bitwidth = _insn->src_bitwidth;
+    int64_t vlhs = 0;
+    int64_t vrhs = 0;
+    if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth)) {
+        sv_sreg_t result = lhs / rhs;
+        fprintf(stderr, "div result %lx %lx %lx\n",
+                (uint64_t)lhs, (uint64_t)rhs, (int64_t)result);
+        return result;
+    }
+    int64_t result = vlhs / vrhs;
+    return rv_int_op_finish(lhs, rhs, result, bitwidth);
 }
 
 sv_reg_t sv_proc_t::rv_div(sv_reg_t const & lhs, sv_reg_t const & rhs)
index 82100c5027739bb5f8e3957d6cc60bc8b7f60c0e..28659affb97011e29b5d2b847682743d1632349b 100644 (file)
@@ -269,8 +269,13 @@ public:
     bool rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs,
                            uint64_t &vlhs, uint64_t &vrhs,
                            uint8_t &bitwidth);
+    bool rv_int_op_prepare(sv_sreg_t const & lhs, sv_sreg_t const & rhs,
+                           int64_t &vlhs, int64_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);
+    sv_sreg_t rv_int_op_finish(sv_sreg_t const & lhs, sv_sreg_t const & rhs,
+                                 int64_t &result, uint8_t &bitwidth);
 
 #include "sv_insn_decl.h"
 };