aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rtlil.cc
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2021-06-09 18:41:57 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2021-06-09 19:53:44 +0200
commit1667ad658b3aefd3b5418dace6403d3990029fb9 (patch)
tree02266fe5b4cc93024bd13739ebc3b3302988aedf /kernel/rtlil.cc
parent12b3a9765dafeb8766265c82dee9e06435343e66 (diff)
downloadyosys-1667ad658b3aefd3b5418dace6403d3990029fb9.tar.gz
yosys-1667ad658b3aefd3b5418dace6403d3990029fb9.tar.bz2
yosys-1667ad658b3aefd3b5418dace6403d3990029fb9.zip
opt_expr: Fix mul/div/mod by POT patterns to support >= 32 bits.
The previous code, in addition to being needlessly limitted to 32 bits in the first place, also had UB for the 31th bit (doing 1 << 31).
Diffstat (limited to 'kernel/rtlil.cc')
-rw-r--r--kernel/rtlil.cc33
1 files changed, 33 insertions, 0 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 1d41ba81a..a756218f3 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -363,6 +363,26 @@ bool RTLIL::Const::is_fully_undef() const
return true;
}
+bool RTLIL::Const::is_onehot(int *pos) const
+{
+ cover("kernel.rtlil.const.is_onehot");
+
+ bool found = false;
+ for (int i = 0; i < GetSize(*this); i++) {
+ auto &bit = bits[i];
+ if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1)
+ return false;
+ if (bit == RTLIL::State::S1) {
+ if (found)
+ return false;
+ if (pos)
+ *pos = i;
+ found = true;
+ }
+ }
+ return found;
+}
+
bool RTLIL::AttrObject::has_attribute(RTLIL::IdString id) const
{
return attributes.count(id);
@@ -4211,6 +4231,19 @@ bool RTLIL::SigSpec::has_marked_bits() const
return false;
}
+bool RTLIL::SigSpec::is_onehot(int *pos) const
+{
+ cover("kernel.rtlil.sigspec.is_onehot");
+
+ pack();
+ if (!is_fully_const())
+ return false;
+ log_assert(GetSize(chunks_) <= 1);
+ if (width_)
+ return RTLIL::Const(chunks_[0].data).is_onehot(pos);
+ return false;
+}
+
bool RTLIL::SigSpec::as_bool() const
{
cover("kernel.rtlil.sigspec.as_bool");