From 60099e5005aa4f67cde989aaee46711eb511c4c2 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 29 Aug 2025 03:09:19 +0000 Subject: [PATCH] Make Const::as_bool and Const::as_int work with packed bits without decaying to vector --- kernel/rtlil.cc | 33 ++++++++++++++++++++++++--------- tests/unit/kernel/rtlilTest.cc | 11 +++++++++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 243098d54..a74b92f9d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -383,7 +383,13 @@ std::vector RTLIL::Const::to_bits() const bool RTLIL::Const::as_bool() const { - bitvectorize_internal(); + if (is_str()) { + for (char ch : get_str()) + if (ch != 0) + return true; + return false; + } + bitvectype& bv = get_bits(); for (size_t i = 0; i < bv.size(); i++) if (bv[i] == State::S1) @@ -393,15 +399,24 @@ bool RTLIL::Const::as_bool() const int RTLIL::Const::as_int(bool is_signed) const { - bitvectorize_internal(); - bitvectype& bv = get_bits(); int32_t ret = 0; - for (size_t i = 0; i < bv.size() && i < 32; i++) + if (is_str()) { + const std::string& s = get_str(); + int size = GetSize(s); + for (int i = std::min(4, size); i > 0; i--) + ret |= static_cast(s[size - i]) << ((i - 1) * 8); + if (is_signed && size > 0 && size < 4 && (s[0] & 0x80)) + ret |= -1 << size*8; + return ret; + } + + const bitvectype& bv = get_bits(); + int significant_bits = std::min(GetSize(bv), 32); + for (int i = 0; i < significant_bits; i++) if (bv[i] == State::S1) ret |= 1 << i; - if (is_signed && bv.back() == State::S1) - for (size_t i = bv.size(); i < 32; i++) - ret |= 1 << i; + if (is_signed && significant_bits > 0 && significant_bits < 32 && bv.back() == State::S1 ) + ret |= -1 << significant_bits; return ret; } @@ -421,7 +436,7 @@ bool RTLIL::Const::convertible_to_int(bool is_signed) const if (size == 32) { if (is_signed) return true; - return get_bits().at(31) != State::S1; + return back() != State::S1; } return false; @@ -442,7 +457,7 @@ int RTLIL::Const::as_int_saturating(bool is_signed) const const auto min_size = get_min_size(is_signed); log_assert(min_size > 0); - const auto neg = get_bits().at(min_size - 1); + const auto neg = (*this)[min_size - 1]; return neg ? std::numeric_limits::min() : std::numeric_limits::max(); } return as_int(is_signed); diff --git a/tests/unit/kernel/rtlilTest.cc b/tests/unit/kernel/rtlilTest.cc index 0b7fbfd37..99ddf44cc 100644 --- a/tests/unit/kernel/rtlilTest.cc +++ b/tests/unit/kernel/rtlilTest.cc @@ -92,12 +92,14 @@ namespace RTLIL { Const c(0x12345678); EXPECT_TRUE(c.is_str()); EXPECT_EQ(c.as_int(), 0x12345678); + EXPECT_TRUE(c.is_str()); } { Const c(0xab, 8); EXPECT_TRUE(c.is_str()); EXPECT_EQ(c.as_int(), 0xab); + EXPECT_TRUE(c.is_str()); } { @@ -105,6 +107,7 @@ namespace RTLIL { EXPECT_TRUE(c.is_str()); EXPECT_EQ(c.as_int(), 0x12345678); EXPECT_EQ(c[79], S0); + EXPECT_TRUE(c.is_str()); } { @@ -112,6 +115,14 @@ namespace RTLIL { EXPECT_TRUE(c.is_str()); EXPECT_EQ(c.as_int(), -1); EXPECT_EQ(c[79], S1); + EXPECT_TRUE(c.is_str()); + } + + { + Const c(1 << 24); + EXPECT_TRUE(c.is_str()); + EXPECT_TRUE(c.as_bool()); + EXPECT_TRUE(c.is_str()); } }