Careful not to lose bits parameter add expression
Parameter expressions that do not otherwise have a size should evaluate expressions losslessly, expanding as necessary to prevent overflow of data. Signed-off-by: Stephen Williams <steve@icarus.com>
This commit is contained in:
parent
59a43ab2ce
commit
a6f898a702
12
PExpr.h
12
PExpr.h
|
|
@ -79,9 +79,15 @@ class PExpr : public LineInfo {
|
|||
|
||||
// Procedural elaboration of the expression. The expr_width is
|
||||
// the width of the context of the expression (i.e. the
|
||||
// l-value width of an assignment) or -1 if the expression is
|
||||
// self-determinted. The sys_task_arg flag is true if
|
||||
// expressions are allowed to be incomplete.
|
||||
// l-value width of an assignment),
|
||||
//
|
||||
// ... or -1 if the expression is self-determined. or
|
||||
// ... or -2 if the expression is losslessly
|
||||
// self-determined. This can happen in situations where the
|
||||
// result is going to a pseudo-infinitely wide context.
|
||||
//
|
||||
// The sys_task_arg flag is true if expressions are allowed to
|
||||
// be incomplete.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
int expr_width, bool sys_task_arg) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
|||
|
||||
case '+':
|
||||
case '-':
|
||||
tmp = new NetEBAdd(op_, lp, rp);
|
||||
tmp = new NetEBAdd(op_, lp, rp, expr_wid==-2? true : false);
|
||||
if (expr_wid > 0 && (tmp->expr_type() == IVL_VT_BOOL
|
||||
|| tmp->expr_type() == IVL_VT_LOGIC))
|
||||
tmp->set_width(expr_wid);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp, -1);
|
||||
NetEBinary*tmp = elaborate_expr_base_(des, lp, rp, -2);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1754,6 +1754,10 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
|
|||
{
|
||||
assert(scope);
|
||||
|
||||
if (debug_elaborate)
|
||||
cerr << get_line() << ": debug: Elaborate condition statement"
|
||||
<< " with conditional: " << *expr_ << endl;
|
||||
|
||||
// Elaborate and try to evaluate the conditional expression.
|
||||
NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
|
||||
if (expr == 0) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ ivl_variable_type_t NetExpr::expr_type() const
|
|||
* Create an add/sub node from the two operands. Make a best guess of
|
||||
* the
|
||||
*/
|
||||
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
|
||||
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r, bool lossless_flag)
|
||||
: NetEBinary(op, l, r)
|
||||
{
|
||||
NetEConst* tmp;
|
||||
|
|
@ -75,14 +75,16 @@ NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
|
|||
|
||||
}
|
||||
|
||||
unsigned pad_width = lossless_flag? 1 : 0;
|
||||
|
||||
/* Now that we have the operand sizes the way we like, or as
|
||||
good as we are going to get them, set the size of myself. */
|
||||
if (r->expr_width() > l->expr_width()) {
|
||||
|
||||
expr_width(r->expr_width());
|
||||
expr_width(r->expr_width() + pad_width);
|
||||
|
||||
} else {
|
||||
expr_width(l->expr_width());
|
||||
expr_width(l->expr_width() + pad_width);
|
||||
}
|
||||
|
||||
cast_signed(l->has_sign() && r->has_sign());
|
||||
|
|
|
|||
Loading…
Reference in New Issue