From 1667ad658b3aefd3b5418dace6403d3990029fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcelina=20Ko=C5=9Bcielnicka?= Date: Wed, 9 Jun 2021 18:41:57 +0200 Subject: 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). --- kernel/rtlil.cc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'kernel/rtlil.cc') 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"); -- cgit v1.2.3