// 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;
}
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?
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)