Pass unsigned-ness of arithmetic operators through operands.
The arithmetic operands are signed only if both operands are signed. If the expression is unsigned, then the expression as a whole needs to be processed as unsigned in order to get padding right.
This commit is contained in:
parent
86bf6c447b
commit
c4a62dee0d
|
|
@ -3262,6 +3262,7 @@ class NetEBAdd : public NetEBinary {
|
|||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual bool set_width(unsigned w, bool last_chance);
|
||||
virtual void cast_signed(bool sign_flag);
|
||||
virtual NetEBAdd* dup_expr() const;
|
||||
virtual NetExpr* eval_tree(int prune_to_width = -1);
|
||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
|
@ -3284,6 +3285,7 @@ class NetEBDiv : public NetEBinary {
|
|||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual bool set_width(unsigned w, bool last_chance);
|
||||
virtual void cast_signed(bool sign_flag);
|
||||
virtual NetEBDiv* dup_expr() const;
|
||||
virtual NetExpr* eval_tree(int prune_to_width = -1);
|
||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
|
@ -3414,6 +3416,7 @@ class NetEBMult : public NetEBinary {
|
|||
virtual ivl_variable_type_t expr_type() const;
|
||||
|
||||
virtual bool set_width(unsigned w, bool last_chance);
|
||||
virtual void cast_signed(bool sign_flag);
|
||||
virtual NetEBMult* dup_expr() const;
|
||||
virtual NetExpr* eval_tree(int prune_to_width = -1);
|
||||
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);
|
||||
|
|
|
|||
38
set_width.cc
38
set_width.cc
|
|
@ -106,6 +106,18 @@ bool NetEBAdd::set_width(unsigned w, bool)
|
|||
return wid == w;
|
||||
}
|
||||
|
||||
void NetEBAdd::cast_signed(bool sign_flag)
|
||||
{
|
||||
if (has_sign() == sign_flag)
|
||||
return;
|
||||
|
||||
if (sign_flag == false) {
|
||||
left_->cast_signed(sign_flag);
|
||||
right_->cast_signed(sign_flag);
|
||||
}
|
||||
cast_signed_base_(sign_flag);
|
||||
}
|
||||
|
||||
/*
|
||||
* The bitwise logical operators have operands the same size as the
|
||||
* result. Anything else is a mess. I first try to get the operands to
|
||||
|
|
@ -168,6 +180,19 @@ bool NetEBDiv::set_width(unsigned w, bool)
|
|||
return w == expr_width();
|
||||
}
|
||||
|
||||
void NetEBDiv::cast_signed(bool sign_flag)
|
||||
{
|
||||
if (has_sign() == sign_flag)
|
||||
return;
|
||||
|
||||
if (sign_flag == false) {
|
||||
left_->cast_signed(sign_flag);
|
||||
right_->cast_signed(sign_flag);
|
||||
}
|
||||
|
||||
cast_signed_base_(sign_flag);
|
||||
}
|
||||
|
||||
bool NetEBLogic::set_width(unsigned w, bool)
|
||||
{
|
||||
bool flag;
|
||||
|
|
@ -192,6 +217,19 @@ bool NetEBMult::set_width(unsigned w, bool)
|
|||
return true;
|
||||
}
|
||||
|
||||
void NetEBMult::cast_signed(bool sign_flag)
|
||||
{
|
||||
if (has_sign() == sign_flag)
|
||||
return;
|
||||
|
||||
if (sign_flag == false) {
|
||||
left_->cast_signed(sign_flag);
|
||||
right_->cast_signed(sign_flag);
|
||||
}
|
||||
|
||||
cast_signed_base_(sign_flag);
|
||||
}
|
||||
|
||||
bool NetEBPow::set_width(unsigned w, bool last_chance)
|
||||
{
|
||||
return w == expr_width();
|
||||
|
|
|
|||
Loading…
Reference in New Issue