Compile time evalutation of constant expressions.
This commit is contained in:
parent
f3a91a10b3
commit
caae00f1fd
29
elaborate.cc
29
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: elaborate.cc,v 1.32 1999/06/02 15:38:46 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.33 1999/06/03 05:16:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -1015,7 +1015,31 @@ NetProc* PCase::elaborate(Design*des, const string&path) const
|
|||
|
||||
NetProc* PCondit::elaborate(Design*des, const string&path) const
|
||||
{
|
||||
// Elaborate and try to evaluate the conditional expression.
|
||||
NetExpr*expr = expr_->elaborate_expr(des, path);
|
||||
NetExpr*tmp = expr->eval_tree();
|
||||
if (tmp) {
|
||||
delete expr;
|
||||
expr = tmp;
|
||||
}
|
||||
|
||||
// If the condition of the conditional statement is constant,
|
||||
// then look at the value and elaborate either the if statement
|
||||
// or the else statement. I don't need both. If there is no
|
||||
// else_ statement, the use an empty block as a noop.
|
||||
if (NetEConst*ce = dynamic_cast<NetEConst*>(expr)) {
|
||||
verinum val = ce->value();
|
||||
delete expr;
|
||||
if (val[0] == verinum::V1)
|
||||
return if_->elaborate(des, path);
|
||||
else if (else_)
|
||||
return else_->elaborate(des, path);
|
||||
else
|
||||
return new NetBlock(NetBlock::SEQU);
|
||||
}
|
||||
|
||||
// Well, I actually need to generate code to handle the
|
||||
// conditional, so elaborate.
|
||||
NetProc*i = if_->elaborate(des, path);
|
||||
NetProc*e = else_? else_->elaborate(des, path) : 0;
|
||||
|
||||
|
|
@ -1248,6 +1272,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.33 1999/06/03 05:16:25 steve
|
||||
* Compile time evalutation of constant expressions.
|
||||
*
|
||||
* Revision 1.32 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
|
|
|
|||
64
netlist.cc
64
netlist.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: netlist.cc,v 1.30 1999/06/02 15:38:46 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.31 1999/06/03 05:16:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
|
@ -404,6 +404,11 @@ bool NetExpr::set_width(unsigned w)
|
|||
return false;
|
||||
}
|
||||
|
||||
NetExpr* NetExpr::eval_tree()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEBinary::NetEBinary(char op, NetExpr*l, NetExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
|
|
@ -426,7 +431,9 @@ bool NetEBinary::set_width(unsigned w)
|
|||
case 'n': /* != */
|
||||
assert(w == 1);
|
||||
expr_width(w);
|
||||
flag = right_->set_width(left_->expr_width());
|
||||
flag = left_->set_width(right_->expr_width());
|
||||
if (!flag)
|
||||
flag = right_->set_width(left_->expr_width());
|
||||
break;
|
||||
|
||||
case 'l': // left shift (<<)
|
||||
|
|
@ -468,6 +475,50 @@ NetEBinary* NetEBinary::dup_expr() const
|
|||
assert(0);
|
||||
}
|
||||
|
||||
NetExpr* NetEBinary::eval_eqeq()
|
||||
{
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
if (l == 0) return 0;
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
if (r == 0) return 0;
|
||||
|
||||
const verinum&lv = l->value();
|
||||
const verinum&rv = r->value();
|
||||
|
||||
if (lv.len() < rv.len())
|
||||
return 0;
|
||||
|
||||
verinum result(verinum::V1, 1);
|
||||
for (unsigned idx = 0 ; idx < lv.len(); idx += 1) {
|
||||
if (lv[idx] != rv[idx])
|
||||
result = verinum::V0;
|
||||
}
|
||||
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
NetExpr* NetEBinary::eval_tree()
|
||||
{
|
||||
NetExpr*tmp = left_->eval_tree();
|
||||
if (tmp) {
|
||||
delete left_;
|
||||
left_ = tmp;
|
||||
}
|
||||
tmp = right_->eval_tree();
|
||||
if (tmp){
|
||||
delete right_;
|
||||
right_ = tmp;
|
||||
}
|
||||
|
||||
switch (op_) {
|
||||
case 'e':
|
||||
return eval_eqeq();
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
NetEConst::~NetEConst()
|
||||
{
|
||||
}
|
||||
|
|
@ -539,11 +590,9 @@ NetESignal::~NetESignal()
|
|||
|
||||
bool NetESignal::set_width(unsigned w)
|
||||
{
|
||||
if (w != pin_count()) {
|
||||
cerr << get_line() << ": " << *this << " cannot be made "
|
||||
<< w << " bits wide." << endl;
|
||||
if (w != pin_count())
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(w == pin_count());
|
||||
expr_width(w);
|
||||
return true;
|
||||
|
|
@ -1069,6 +1118,9 @@ NetNet* Design::find_signal(bool (*func)(const NetNet*))
|
|||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.31 1999/06/03 05:16:25 steve
|
||||
* Compile time evalutation of constant expressions.
|
||||
*
|
||||
* Revision 1.30 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
|
|
|
|||
18
netlist.h
18
netlist.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: netlist.h,v 1.34 1999/06/02 15:38:46 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.35 1999/06/03 05:16:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -338,6 +338,12 @@ class NetExpr : public LineInfo {
|
|||
// coersion works, then return true. Otherwise, return false.
|
||||
virtual bool set_width(unsigned);
|
||||
|
||||
// This method evaluates the expression and returns an
|
||||
// equivilent expression that is reduced as far as compile
|
||||
// time knows how. Essentially, this is designed to fold
|
||||
// constants.
|
||||
virtual NetExpr*eval_tree();
|
||||
|
||||
// Make a duplicate of myself, and subexpressions if I have
|
||||
// any. This is a deep copy operation.
|
||||
virtual NetExpr*dup_expr() const =0;
|
||||
|
|
@ -876,11 +882,18 @@ class NetEBinary : public NetExpr {
|
|||
|
||||
virtual bool set_width(unsigned w);
|
||||
|
||||
// If both of my subexpressions are constants, then I can
|
||||
// probably evaluate this part of the expression at compile
|
||||
// time.
|
||||
virtual NetExpr* eval_tree();
|
||||
|
||||
virtual NetEBinary* dup_expr() const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
NetExpr*eval_eqeq();
|
||||
|
||||
private:
|
||||
char op_;
|
||||
NetExpr* left_;
|
||||
|
|
@ -1165,6 +1178,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.35 1999/06/03 05:16:25 steve
|
||||
* Compile time evalutation of constant expressions.
|
||||
*
|
||||
* Revision 1.34 1999/06/02 15:38:46 steve
|
||||
* Line information with nets.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue