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:
Stephen Williams 2009-03-11 13:22:11 -07:00
parent 86bf6c447b
commit c4a62dee0d
2 changed files with 41 additions and 0 deletions

View File

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

View File

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