From ca5d26535021cf66ff2ee5a8685f786cb42cbeaf Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 5 Dec 2008 10:21:48 -0800 Subject: [PATCH] V0.8: left shift of integer value needs to use integer size This is a back port from development of the code to resize an unsized constant value to 32 bits. Development used integer_width, but that is not supported in V0.8. Development also supports using the expression width which V0.8 does not. --- PExpr.h | 4 ++-- elab_expr.cc | 55 ++++++++++++++++++++++++++++++++++++++++++++++----- elab_pexpr.cc | 2 +- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/PExpr.h b/PExpr.h index 4d1aa9007..e859402f6 100644 --- a/PExpr.h +++ b/PExpr.h @@ -376,7 +376,7 @@ class PEBinary : public PExpr { unsigned long decay, Link::strength_t drive0, Link::strength_t drive1) const; - virtual NetEBinary*elaborate_expr(Design*des, NetScope*, + virtual NetExpr*elaborate_expr(Design*des, NetScope*, bool sys_task_arg =false) const; virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const; virtual verinum* eval_const(const Design*des, const NetScope*sc) const; @@ -386,7 +386,7 @@ class PEBinary : public PExpr { PExpr*left_; PExpr*right_; - NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const; + NetExpr*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const; NetNet* elaborate_net_add_(Design*des, NetScope*scope, unsigned lwidth, diff --git a/elab_expr.cc b/elab_expr.cc index ea112eff4..50ccef2d6 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -43,7 +43,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const * and right sides, and creating one of a variety of different NetExpr * types. */ -NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const +NetExpr* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const { assert(left_); assert(right_); @@ -73,7 +73,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const } } - NetEBinary*tmp = elaborate_expr_base_(des, lp, rp); + NetExpr*tmp = elaborate_expr_base_(des, lp, rp); return tmp; } @@ -82,11 +82,11 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const * operands are elaborated as necessary, and all I need to do is make * the correct NetEBinary object and connect the parameters. */ -NetEBinary* PEBinary::elaborate_expr_base_(Design*des, - NetExpr*lp, NetExpr*rp) const +NetExpr* PEBinary::elaborate_expr_base_(Design*des, + NetExpr*lp, NetExpr*rp) const { bool flag; - NetEBinary*tmp; + NetExpr*tmp; switch (op_) { default: @@ -112,6 +112,51 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des, break; case 'l': // << + if (NetEConst*lpc = dynamic_cast (lp)) { + if (NetEConst*rpc = dynamic_cast (rp)) { + // Handle the super-special case that both + // operands are constants. Precalculate the + // entire value here. + verinum lpval = lpc->value(); + unsigned shift = rpc->value().as_ulong(); + verinum result = lpc->value() << shift; + // If the l-value has explicit size, use that. + if (lpval.has_len()) { + result = verinum(result, lpval.len()); + } + + tmp = new NetEConst(result); + if (debug_elaborate) + cerr << get_line() << ": debug: " + << "Precalculate " << *this + << " to constant " << *tmp << endl; + + } else { + // Handle the special case that the left + // operand is constant. If it is unsized, we + // may have to expand it to an integer width. + verinum lpval = lpc->value(); + if (lpval.len() < 32 && !lpval.has_len()) { + lpval = verinum(lpval, 32); + lpc = new NetEConst(lpval); + lpc->set_line(*lp); + } + + tmp = new NetEBShift(op_, lpc, rp); + if (debug_elaborate) + cerr << get_line() << ": debug: " + << "Adjust " << *this + << " to this " << *tmp + << " to allow for integer widths." << endl; + } + + } else { + // Left side is not constant, so handle it the + // default way. + tmp = new NetEBShift(op_, lp, rp); + } + tmp->set_line(*this); + break; case 'r': // >> case 'R': // >>> tmp = new NetEBShift(op_, lp, rp); diff --git a/elab_pexpr.cc b/elab_pexpr.cc index ba9730e96..f65e660bb 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -53,7 +53,7 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const return 0; } - NetEBinary*tmp = elaborate_expr_base_(des, lp, rp); + NetExpr*tmp = elaborate_expr_base_(des, lp, rp); return tmp; }