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