summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-08-15 18:23:42 +0200
committerClifford Wolf <clifford@clifford.at>2013-08-15 18:23:42 +0200
commit78658199e662979c8f9223be53b04c9d87a1d6f7 (patch)
treef6a5956be6af6564a7d2d050719829a12ef8631f /kernel
parent457dc09cdc3546d70eb347d35ad28ffca1621f7d (diff)
Fixed signed div/mod in const eval (rounding and stuff)
Diffstat (limited to 'kernel')
-rw-r--r--kernel/calc.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/calc.cc b/kernel/calc.cc
index 8034ed2c..2e9be437 100644
--- a/kernel/calc.cc
+++ b/kernel/calc.cc
@@ -366,7 +366,10 @@ RTLIL::Const RTLIL::const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2
BigInteger b = const2big(arg2, signed2, undef_bit_pos);
if (b.isZero())
return RTLIL::Const(RTLIL::State::Sx, result_len);
- return big2const(a / b, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
+ bool result_neg = (a.getSign() == BigInteger::negative) != (b.getSign() == BigInteger::negative);
+ a = a.getSign() == BigInteger::negative ? -a : a;
+ b = b.getSign() == BigInteger::negative ? -b : b;
+ return big2const(result_neg ? -(a / b) : (a / b), result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
@@ -376,7 +379,10 @@ RTLIL::Const RTLIL::const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2
BigInteger b = const2big(arg2, signed2, undef_bit_pos);
if (b.isZero())
return RTLIL::Const(RTLIL::State::Sx, result_len);
- return big2const(a % b, result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
+ bool result_neg = a.getSign() == BigInteger::negative;
+ a = a.getSign() == BigInteger::negative ? -a : a;
+ b = b.getSign() == BigInteger::negative ? -b : b;
+ return big2const(result_neg ? -(a % b) : (a % b), result_len >= 0 ? result_len : std::max(arg1.bits.size(), arg2.bits.size()), std::min(undef_bit_pos, 0));
}
RTLIL::Const RTLIL::const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)