From 4c8a7b221c531d53c25c1c454846356d64e45089 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Mon, 17 Dec 2007 21:00:18 -0800 Subject: [PATCH] Proper padding of constant bitwise operands When evaluating bitwise binary expressions at compile time, get the signed/unsigned padding correct. Pay special attention to the case of $signed/$unsigned changing the signedness of the operand. --- eval_tree.cc | 11 +++++++++++ netlist.cc | 2 +- netlist.h | 5 +++-- set_width.cc | 6 ++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/eval_tree.cc b/eval_tree.cc index 2f2e877cc..19558bbdc 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -248,6 +248,17 @@ NetEConst* NetEBBits::eval_tree(int prune_to_width) if (rwid > wid) rwid = wid; + // Sub-expressions of bitwise operators need to be the same + // width. Pad them out if necessary. + if (lwid < wid) { + lval = pad_to_width(lval, wid); + lwid = wid; + } + if (rwid < wid) { + rval = pad_to_width(rval, wid); + rwid = wid; + } + switch (op()) { case '|': { diff --git a/netlist.cc b/netlist.cc index 97e328b80..9321eaeae 100644 --- a/netlist.cc +++ b/netlist.cc @@ -2002,7 +2002,7 @@ NetEBLogic* NetEBLogic::dup_expr() const NetEConst::NetEConst(const verinum&val) : NetExpr(val.len()), value_(val) { - cast_signed(value_.has_sign()); + cast_signed_base_(value_.has_sign()); } NetEConst::~NetEConst() diff --git a/netlist.h b/netlist.h index 9f1ec6d98..022187df3 100644 --- a/netlist.h +++ b/netlist.h @@ -1103,7 +1103,7 @@ class NetExpr : public LineInfo { // This method returns true if the expression is // signed. Unsigned expressions return false. bool has_sign() const; - void cast_signed(bool flag); + virtual void cast_signed(bool flag); // This returns true if the expression has a definite // width. This is generally true, but in some cases the @@ -1145,6 +1145,7 @@ class NetExpr : public LineInfo { protected: void expr_width(unsigned w) { width_ = w; } + void cast_signed_base_(bool flag) {signed_flag_ = flag; } private: unsigned width_; @@ -1169,7 +1170,7 @@ class NetEConst : public NetExpr { const verinum&value() const; virtual bool set_width(unsigned w, bool last_chance =false); - + virtual void cast_signed(bool sign_flag); virtual bool has_width() const; virtual ivl_variable_type_t expr_type() const; diff --git a/set_width.cc b/set_width.cc index e293ca192..c15b9521b 100644 --- a/set_width.cc +++ b/set_width.cc @@ -326,6 +326,12 @@ bool NetEConst::set_width(unsigned w, bool last_chance) } } +void NetEConst::cast_signed(bool sign_flag) +{ + value_.has_sign(sign_flag); + cast_signed_base_(sign_flag); +} + /* * Parameter vectors cannot be resized because they refer to a common * value.