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.
This commit is contained in:
Stephen Williams 2007-12-17 21:00:18 -08:00
parent 752cf21790
commit 4c8a7b221c
4 changed files with 21 additions and 3 deletions

View File

@ -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 '|': {

View File

@ -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()

View File

@ -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;

View File

@ -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.