Handle multiply with constant zero.

Multiply of any expression with constant 0 will always return zero.
We can handle this early, during elaboration, and save a lot of code
downstream the trouble.

Also, while we are at it, fix up test_width to re-test the left
expression width if the right expression width is unsized. This allows
for the left expression code to adapt to the unsized-ness of the
expression context.
This commit is contained in:
Stephen Williams 2008-10-04 20:01:19 -07:00
parent 18de6980ff
commit 03fd124d5a
1 changed files with 34 additions and 2 deletions

View File

@ -115,14 +115,20 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope,
ivl_variable_type_t&expr_type,
bool&unsized_flag) const
{
bool flag_left = false;
bool flag_right = false;
ivl_variable_type_t expr_type_left = IVL_VT_NO_TYPE;
ivl_variable_type_t expr_type_right= IVL_VT_NO_TYPE;
bool flag_left = unsized_flag;
unsigned wid_left = left_->test_width(des,scope, min, 0, expr_type_left, flag_left);
bool flag_right = flag_left;
unsigned wid_right = right_->test_width(des,scope, min, 0, expr_type_right, flag_right);
if (flag_right && !flag_left) {
flag_left = flag_right;
wid_left = left_->test_width(des, scope, min, 0, expr_type_right, flag_right);
}
if (flag_left || flag_right)
unsized_flag = true;
@ -624,6 +630,32 @@ NetExpr* PEBinary::elaborate_expr_base_mult_(Design*des,
rp = pad_to_width(rp, expr_wid);
}
// Keep constants on the right side.
if (dynamic_cast<NetEConst*>(lp)) {
NetExpr*tmp = lp;
lp = rp;
rp = tmp;
}
// Handle a few special case multiplies against constants.
if (NetEConst*rp_const = dynamic_cast<NetEConst*> (rp)) {
verinum rp_val = rp_const->value();
int use_wid = expr_wid;
if (use_wid < 0)
use_wid = max(rp->expr_width(), lp->expr_width());
if (! rp_val.is_defined()) {
NetEConst*tmp = make_const_x(use_wid);
return tmp;
}
if (rp_val.is_zero()) {
NetEConst*tmp = make_const_0(use_wid);
return tmp;
}
}
// Multiply will guess a width that is the sum of the
// widths of the operand. If that sum is too small, then
// pad one of the arguments enough that the sum is the