Skip to content

Commit

Permalink
rtlil: refactoring out of header
Browse files Browse the repository at this point in the history
  • Loading branch information
widlarizer committed Sep 11, 2024
1 parent a4ead4f commit eedf770
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 86 deletions.
70 changes: 70 additions & 0 deletions kernel/rtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,16 @@ const pool<IdString> &RTLIL::builtin_ff_cell_types() {
return res;
}

Const::bitvectype& Const::get_bits() const {
log_assert(is_bits() && "malformed Const union");
return *get_if_bits();
}

std::string& Const::get_str() const {
log_assert(is_str() && "malformed Const union");
return *get_if_str();
}

RTLIL::Const::Const(const std::string &str)
{
flags = RTLIL::CONST_FLAG_STRING;
Expand Down Expand Up @@ -436,6 +446,58 @@ std::string RTLIL::Const::decode_string() const
return s;
}

int RTLIL::Const::size() const {
if (is_str())
return 8 * str_.size();
else {
log_assert(is_bits() && "malformed Const union");
return bits_.size();
}
}

bool RTLIL::Const::empty() const {
if (is_str())
return str_.empty();
else {
log_assert(is_bits() && "malformed Const union");
return bits_.empty();
}
}

void RTLIL::Const::bitvectorize() const {
if (tag == backing_tag::bits)
return;

log_assert(is_str() && "malformed Const union");

bitvectype new_bits;

new_bits.reserve(str_.size() * 8);
for (int i = str_.size() - 1; i >= 0; i--) {
unsigned char ch = str_[i];
for (int j = 0; j < 8; j++) {
new_bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);
ch = ch >> 1;
}
}

{
// sketchy zone
str_.~string();
(void)new ((void*)&bits_) bitvectype(std::move(new_bits));
tag = backing_tag::bits;
}
}

RTLIL::State RTLIL::Const::const_iterator::operator*() const {
if (auto bv = parent.get_if_bits())
return (*bv)[idx];

int char_idx = parent.get_str().size() - idx / 8 - 1;
bool bit = (parent.get_str()[char_idx] & (1 << (idx % 8)));
return bit ? State::S1 : State::S0;
}

bool RTLIL::Const::is_fully_zero() const
{
bitvectorize();
Expand Down Expand Up @@ -527,6 +589,14 @@ bool RTLIL::Const::is_onehot(int *pos) const
return found;
}

RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) const {
bitvectype ret_bv;
ret_bv.reserve(len);
for (int i = offset; i < offset + len; i++)
ret_bv.push_back(i < GetSize(*this) ? (*this)[i] : padding);
return RTLIL::Const(ret_bv);
}

bool RTLIL::AttrObject::has_attribute(const RTLIL::IdString &id) const
{
return attributes.count(id);
Expand Down
100 changes: 14 additions & 86 deletions kernel/rtlil.h
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ struct RTLIL::Const
{
short flags;
private:
typedef std::vector<RTLIL::State> bitvectype;
using bitvectype = std::vector<RTLIL::State>;
enum class backing_tag: bool { bits, string };
// Do not access the union or tag even in Const methods unless necessary
mutable backing_tag tag;
Expand All @@ -676,21 +676,15 @@ struct RTLIL::Const
mutable std::string str_;
};

// Use these utilities instead
// Use these private utilities instead
bool is_bits() const { return tag == backing_tag::bits; }
bool is_str() const { return tag == backing_tag::string; }

bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; }
std::string* get_if_str() const { return is_str() ? &str_ : NULL; }

bitvectype& get_bits() const {
log_assert(is_bits() && "malformed Const union");
return *get_if_bits();
}
std::string& get_str() const {
log_assert(is_str() && "malformed Const union");
return *get_if_str();
}
bitvectype& get_bits() const;
std::string& get_str() const;
public:
Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector<RTLIL::State>()) {}
Const(const std::string &str);
Expand All @@ -715,48 +709,9 @@ struct RTLIL::Const
std::vector<RTLIL::State> to_bits() const;

std::string decode_string() const;
inline int size() const {
if (is_str())
return 8 * str_.size();
else {
log_assert(is_bits() && "malformed Const union");
return bits_.size();
}
}

inline bool empty() const {
if (is_str())
return str_.empty();
else {
log_assert(is_bits() && "malformed Const union");
return bits_.empty();
}
}

void bitvectorize() const {
if (tag == backing_tag::bits)
return;

log_assert(is_str() && "malformed Const union");

bitvectype new_bits;

new_bits.reserve(str_.size() * 8);
for (int i = str_.size() - 1; i >= 0; i--) {
unsigned char ch = str_[i];
for (int j = 0; j < 8; j++) {
new_bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);
ch = ch >> 1;
}
}

{
// sketchy zone
str_.~string();
(void)new ((void*)&bits_) bitvectype(std::move(new_bits));
tag = backing_tag::bits;
}
}
int size() const;
bool empty() const;
void bitvectorize() const;

class const_iterator {
private:
Expand All @@ -772,34 +727,13 @@ struct RTLIL::Const

const_iterator(const Const& c, size_t i) : parent(c), idx(i) {}

State operator*() const {
if (auto bv = parent.get_if_bits())
return (*bv)[idx];
State operator*() const;

int char_idx = parent.get_str().size() - idx / 8 - 1;
bool bit = (parent.get_str()[char_idx] & (1 << (idx % 8)));
return bit ? State::S1 : State::S0;
}
const_iterator& operator++() {
++idx;
return *this;
}
const_iterator& operator--() {
--idx;
return *this;
}
const_iterator& operator++(int) {
++idx;
return *this;
}
const_iterator& operator--(int) {
--idx;
return *this;
}
const_iterator& operator+=(int i) {
idx += i;
return *this;
}
const_iterator& operator++() { ++idx; return *this; }
const_iterator& operator--() { --idx; return *this; }
const_iterator& operator++(int) { ++idx; return *this; }
const_iterator& operator--(int) { --idx; return *this; }
const_iterator& operator+=(int i) { idx += i; return *this; }

const_iterator operator+(int add) {
return const_iterator(parent, idx + add);
Expand Down Expand Up @@ -846,13 +780,7 @@ struct RTLIL::Const
bool is_fully_undef_x_only() const;
bool is_onehot(int *pos = nullptr) const;

inline RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const {
bitvectype ret_bv;
ret_bv.reserve(len);
for (int i = offset; i < offset + len; i++)
ret_bv.push_back(i < GetSize(*this) ? (*this)[i] : padding);
return RTLIL::Const(ret_bv);
}
RTLIL::Const extract(int offset, int len = 1, RTLIL::State padding = RTLIL::State::S0) const;

void extu(int width) {
bits().resize(width, RTLIL::State::S0);
Expand Down

0 comments on commit eedf770

Please sign in to comment.