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 ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBAdd* dup_expr() const; virtual NetEBAdd* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); 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 ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBDiv* dup_expr() const; virtual NetEBDiv* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); 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 ivl_variable_type_t expr_type() const;
virtual bool set_width(unsigned w, bool last_chance); virtual bool set_width(unsigned w, bool last_chance);
virtual void cast_signed(bool sign_flag);
virtual NetEBMult* dup_expr() const; virtual NetEBMult* dup_expr() const;
virtual NetExpr* eval_tree(int prune_to_width = -1); virtual NetExpr* eval_tree(int prune_to_width = -1);
virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root); virtual NetNet* synthesize(Design*, NetScope*scope, NetExpr*root);

View File

@ -106,6 +106,18 @@ bool NetEBAdd::set_width(unsigned w, bool)
return wid == w; 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 * 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 * 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(); 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 NetEBLogic::set_width(unsigned w, bool)
{ {
bool flag; bool flag;
@ -192,6 +217,19 @@ bool NetEBMult::set_width(unsigned w, bool)
return true; 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) bool NetEBPow::set_width(unsigned w, bool last_chance)
{ {
return w == expr_width(); return w == expr_width();