Fix special case that one of the arguments of a compare is a real expression.

If one of the arguments of a comparison expression has a real value, then
the expression with is 1 no matter the width of the other argument. This
means that the arguments may have different widths in this special case.
Patch is from pr2251119, suggested by Martin Whitaker.
This commit is contained in:
Stephen Williams 2008-11-15 21:42:02 -08:00
parent a42eb5cf94
commit 4892e93a09
1 changed files with 16 additions and 10 deletions

View File

@ -749,20 +749,26 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
left_width = left_->test_width(des, scope, 0, 0, left_type, unsized_flag);
/* Width of operands is self-determined. */
int use_wid = left_width;
if (right_width > left_width)
use_wid = right_width;
int use_wid_l = left_width;
if (type_is_vectorable(left_type) && (right_width > left_width))
use_wid_l = right_width;
int use_wid_r = right_width;
if (type_is_vectorable(right_type) && (left_width > right_width))
use_wid_r = left_width;
if (debug_elaborate) {
cerr << get_fileline() << ": debug: "
<< "Comparison expression operands are "
<< left_width << " bits and "
<< right_width << " bits. Resorting to "
<< use_wid << " bits." << endl;
<< use_wid_l << " bits and "
<< use_wid_r << " bits." << endl;
}
NetExpr*lp = left_->elaborate_expr(des, scope, use_wid, false);
NetExpr*rp = right_->elaborate_expr(des, scope, use_wid, false);
NetExpr*lp = left_->elaborate_expr(des, scope, use_wid_l, false);
NetExpr*rp = right_->elaborate_expr(des, scope, use_wid_r, false);
if ((lp == 0) || (rp == 0)) {
delete lp;
delete rp;
@ -775,12 +781,12 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
// pad the width here. This matters because if the arguments
// are signed, then this padding will do sign extension.
if (type_is_vectorable(lp->expr_type()))
lp = pad_to_width(lp, use_wid);
lp = pad_to_width(lp, use_wid_l);
if (type_is_vectorable(rp->expr_type()))
rp = pad_to_width(rp, use_wid);
rp = pad_to_width(rp, use_wid_r);
eval_expr(lp, use_wid);
eval_expr(rp, use_wid);
eval_expr(lp, use_wid_l);
eval_expr(rp, use_wid_r);
// Handle some operand-specific special cases...
switch (op_) {