From 3a99a5e800047ef3464daa5e304f9c76b67aca63 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 11 Oct 2008 08:39:06 -0700 Subject: [PATCH] Suppress operand has_sign if expression is unsigned. Fix processing of arguments of +- and * when only one of the operands is signed. --- PExpr.cc | 1 - PExpr.h | 2 -- elab_expr.cc | 13 +++++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/PExpr.cc b/PExpr.cc index 87fa6ad39..8e1c9889b 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -29,7 +29,6 @@ PExpr::PExpr() { expr_type_ = IVL_VT_NO_TYPE; - has_sign_ = false; } PExpr::~PExpr() diff --git a/PExpr.h b/PExpr.h index 7237cbc2f..e0e0f745a 100644 --- a/PExpr.h +++ b/PExpr.h @@ -79,7 +79,6 @@ class PExpr : public LineInfo { // return valid results. ivl_variable_type_t expr_type() const { return expr_type_; } unsigned expr_width() const { return expr_width_; } - bool has_sign() const { return has_sign_; } // During the elaborate_sig phase, we may need to scan // expressions to find implicit net declarations. @@ -144,7 +143,6 @@ class PExpr : public LineInfo { // The derived class test_width methods should fill these in. ivl_variable_type_t expr_type_; unsigned expr_width_; - bool has_sign_; private: // not implemented PExpr(const PExpr&); diff --git a/elab_expr.cc b/elab_expr.cc index d73863d76..ab3785657 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -662,6 +662,12 @@ NetExpr* PEBinary::elaborate_expr_base_mult_(Design*des, } } + // If this expression is unsigned, then make sure the + // arguments are unsigned so that the padding below doesn't + // cause any sign extension to happen. + suppress_operand_sign_if_needed_(lp, rp); + + // 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 @@ -693,6 +699,11 @@ NetExpr* PEBinary::elaborate_expr_base_add_(Design*des, if (! type_is_vectorable(rp->expr_type())) use_lossless_flag = false; + // If the expression is unsigned, then force the operands to + // unsigned so taht the set_width below doesn't cause them to + // be sign-extended. + suppress_operand_sign_if_needed_(lp, rp); + tmp = new NetEBAdd(op_, lp, rp, use_lossless_flag); if (expr_wid > 0 && type_is_vectorable(tmp->expr_type())) tmp->set_width(expr_wid); @@ -839,7 +850,6 @@ unsigned PECallFunction::test_width_sfunc_(Design*des, NetScope*scope, expr_type_ = IVL_VT_BOOL; expr_width_= integer_width; - has_sign_ = false; expr_type = expr_type_; return expr_width_; @@ -1345,7 +1355,6 @@ unsigned PEFNumber::test_width(Design*des, NetScope*scope, { expr_type_ = IVL_VT_REAL; expr_width_ = 1; - has_sign_ = true; unsized_flag = true; expr_type = expr_type_;