Add support for indexed select attached to parameters.
This commit is contained in:
parent
16dc3ab4d4
commit
a652719876
7
PExpr.cc
7
PExpr.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PExpr.cc,v 1.36 2005/08/06 17:58:16 steve Exp $"
|
#ident "$Id: PExpr.cc,v 1.37 2005/10/04 04:09:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -148,7 +148,7 @@ bool PEFNumber::is_constant(Module*) const
|
||||||
}
|
}
|
||||||
|
|
||||||
PEIdent::PEIdent(const hname_t&s)
|
PEIdent::PEIdent(const hname_t&s)
|
||||||
: path_(s), msb_(0), lsb_(0), idx_(0)
|
: path_(s), msb_(0), lsb_(0), sel_(SEL_NONE), idx_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,6 +270,9 @@ bool PEUnary::is_constant(Module*m) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.cc,v $
|
* $Log: PExpr.cc,v $
|
||||||
|
* Revision 1.37 2005/10/04 04:09:25 steve
|
||||||
|
* Add support for indexed select attached to parameters.
|
||||||
|
*
|
||||||
* Revision 1.36 2005/08/06 17:58:16 steve
|
* Revision 1.36 2005/08/06 17:58:16 steve
|
||||||
* Implement bi-directional part selects.
|
* Implement bi-directional part selects.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
11
PExpr.h
11
PExpr.h
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: PExpr.h,v 1.70 2005/08/06 17:58:16 steve Exp $"
|
#ident "$Id: PExpr.h,v 1.71 2005/10/04 04:09:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
@ -252,6 +252,10 @@ class PEIdent : public PExpr {
|
||||||
const hname_t& path() const;
|
const hname_t& path() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
NetExpr*elaborate_expr_param(Design*des,
|
||||||
|
NetScope*scope,
|
||||||
|
const NetExpr*par,
|
||||||
|
NetScope*found) const;
|
||||||
hname_t path_;
|
hname_t path_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -259,6 +263,8 @@ class PEIdent : public PExpr {
|
||||||
PExpr*msb_;
|
PExpr*msb_;
|
||||||
PExpr*lsb_;
|
PExpr*lsb_;
|
||||||
|
|
||||||
|
enum { SEL_NONE, SEL_BIT, SEL_PART, SEL_IDX_UP, SEL_IDX_DO } sel_;
|
||||||
|
|
||||||
// If this is a reference to a memory, this is the index
|
// If this is a reference to a memory, this is the index
|
||||||
// expression.
|
// expression.
|
||||||
PExpr*idx_;
|
PExpr*idx_;
|
||||||
|
|
@ -517,6 +523,9 @@ class PECallFunction : public PExpr {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: PExpr.h,v $
|
* $Log: PExpr.h,v $
|
||||||
|
* Revision 1.71 2005/10/04 04:09:25 steve
|
||||||
|
* Add support for indexed select attached to parameters.
|
||||||
|
*
|
||||||
* Revision 1.70 2005/08/06 17:58:16 steve
|
* Revision 1.70 2005/08/06 17:58:16 steve
|
||||||
* Implement bi-directional part selects.
|
* Implement bi-directional part selects.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
318
elab_expr.cc
318
elab_expr.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: elab_expr.cc,v 1.97 2005/09/19 21:45:35 steve Exp $"
|
#ident "$Id: elab_expr.cc,v 1.98 2005/10/04 04:09:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -498,142 +498,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
|
||||||
// If the identifier name is a parameter name, then return
|
// If the identifier name is a parameter name, then return
|
||||||
// a reference to the parameter expression.
|
// a reference to the parameter expression.
|
||||||
if (par != 0) {
|
if (par != 0)
|
||||||
NetExpr*tmp;
|
return elaborate_expr_param(des, scope, par, found_in);
|
||||||
|
|
||||||
tmp = par->dup_expr();
|
|
||||||
|
|
||||||
if (msb_ && lsb_) {
|
|
||||||
/* If the parameter has a part select, we support
|
|
||||||
it by pulling the right bits out and making a
|
|
||||||
sized unsigned constant. This code assumes the
|
|
||||||
lsb of a parameter is 0 and the msb is the
|
|
||||||
width of the parameter. */
|
|
||||||
|
|
||||||
verinum*lsn = lsb_->eval_const(des, scope);
|
|
||||||
verinum*msn = msb_->eval_const(des, scope);
|
|
||||||
if ((lsn == 0) || (msn == 0)) {
|
|
||||||
cerr << get_line() << ": error: "
|
|
||||||
"Part select expressions must be "
|
|
||||||
"constant expressions." << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
long lsb = lsn->as_long();
|
|
||||||
long msb = msn->as_long();
|
|
||||||
if ((lsb < 0) || (msb < lsb)) {
|
|
||||||
cerr << get_line() << ": error: invalid part "
|
|
||||||
<< "select: " << path_
|
|
||||||
<< "["<<msb<<":"<<lsb<<"]" << endl;
|
|
||||||
des->errors += 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
unsigned long ulsb=lsb;
|
|
||||||
unsigned long umsb=msb;
|
|
||||||
|
|
||||||
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
|
||||||
assert(le);
|
|
||||||
|
|
||||||
verinum result (verinum::V0, msb-lsb+1, true);
|
|
||||||
verinum exl = le->value();
|
|
||||||
|
|
||||||
/* Pull the bits from the parameter, one at a
|
|
||||||
time. If the bit is within the range, simply
|
|
||||||
copy it to the result. If the bit is outside
|
|
||||||
the range, we sign extend signed unsized
|
|
||||||
numbers, zero extend unsigned unsigned numbers,
|
|
||||||
and X extend sized numbers. */
|
|
||||||
for (unsigned long idx = ulsb ; idx <= umsb ; idx += 1) {
|
|
||||||
if (idx < exl.len())
|
|
||||||
result.set(idx-lsb, exl.get(idx));
|
|
||||||
else if (exl.is_string())
|
|
||||||
result.set(idx-lsb, verinum::V0);
|
|
||||||
else if (exl.has_len())
|
|
||||||
result.set(idx-lsb, verinum::Vx);
|
|
||||||
else if (exl.has_sign())
|
|
||||||
result.set(idx-lsb, exl.get(exl.len()-1));
|
|
||||||
else
|
|
||||||
result.set(idx-lsb, verinum::V0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the input is a string, and the part select
|
|
||||||
is working on byte boundaries, then the result
|
|
||||||
can be made into a string. */
|
|
||||||
if (exl.is_string()
|
|
||||||
&& (lsb%8 == 0)
|
|
||||||
&& (result.len()%8 == 0))
|
|
||||||
result = verinum(result.as_string());
|
|
||||||
|
|
||||||
delete tmp;
|
|
||||||
tmp = new NetEConst(result);
|
|
||||||
|
|
||||||
} else if (msb_) {
|
|
||||||
/* Handle the case where a parameter has a bit
|
|
||||||
select attached to it. Generate a NetESelect
|
|
||||||
object to select the bit as desired. */
|
|
||||||
NetExpr*mtmp = msb_->elaborate_expr(des, scope);
|
|
||||||
if (! dynamic_cast<NetEConst*>(mtmp)) {
|
|
||||||
NetExpr*re = mtmp->eval_tree();
|
|
||||||
if (re) {
|
|
||||||
delete mtmp;
|
|
||||||
mtmp = re;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Let's first try to get constant values for both
|
|
||||||
the parameter and the bit select. If they are
|
|
||||||
both constant, then evaluate the bit select and
|
|
||||||
return instead a single-bit constant. */
|
|
||||||
|
|
||||||
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
|
||||||
NetEConst*re = dynamic_cast<NetEConst*>(mtmp);
|
|
||||||
if (le && re) {
|
|
||||||
|
|
||||||
verinum lv = le->value();
|
|
||||||
verinum rv = re->value();
|
|
||||||
verinum::V rb = verinum::Vx;
|
|
||||||
|
|
||||||
long ridx = rv.as_long();
|
|
||||||
if ((ridx >= 0) && ((unsigned long) ridx < lv.len())) {
|
|
||||||
rb = lv[ridx];
|
|
||||||
|
|
||||||
} else if ((ridx >= 0) && (!lv.has_len())) {
|
|
||||||
if (lv.has_sign())
|
|
||||||
rb = lv[lv.len()-1];
|
|
||||||
else
|
|
||||||
rb = verinum::V0;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetEConst*re = new NetEConst(verinum(rb, 1));
|
|
||||||
delete tmp;
|
|
||||||
delete mtmp;
|
|
||||||
tmp = re;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
NetESelect*stmp = new NetESelect(tmp, mtmp, 1);
|
|
||||||
tmp->set_line(*this);
|
|
||||||
tmp = stmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* No bit or part select. Make the constant into a
|
|
||||||
NetEConstParam if possible. */
|
|
||||||
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
|
|
||||||
if (ctmp != 0) {
|
|
||||||
perm_string name
|
|
||||||
= lex_strings.make(path_.peek_tail_name());
|
|
||||||
NetEConstParam*ptmp
|
|
||||||
= new NetEConstParam(found_in, name, ctmp->value());
|
|
||||||
delete tmp;
|
|
||||||
tmp = ptmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp->set_line(*this);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the identifier names a signal (a register or wire)
|
// If the identifier names a signal (a register or wire)
|
||||||
// then create a NetESignal node to handle it.
|
// then create a NetESignal node to handle it.
|
||||||
|
|
@ -645,6 +512,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
// the foo[msb:lsb] expression in the original.
|
// the foo[msb:lsb] expression in the original.
|
||||||
if (lsb_) {
|
if (lsb_) {
|
||||||
assert(msb_);
|
assert(msb_);
|
||||||
|
assert(sel_ == SEL_PART);
|
||||||
verinum*lsn = lsb_->eval_const(des, scope);
|
verinum*lsn = lsb_->eval_const(des, scope);
|
||||||
verinum*msn = msb_->eval_const(des, scope);
|
verinum*msn = msb_->eval_const(des, scope);
|
||||||
if ((lsn == 0) || (msn == 0)) {
|
if ((lsn == 0) || (msn == 0)) {
|
||||||
|
|
@ -872,6 +740,181 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetExpr* PEIdent::elaborate_expr_param(Design*des,
|
||||||
|
NetScope*scope,
|
||||||
|
const NetExpr*par,
|
||||||
|
NetScope*found_in) const
|
||||||
|
{
|
||||||
|
NetExpr*tmp;
|
||||||
|
|
||||||
|
tmp = par->dup_expr();
|
||||||
|
|
||||||
|
if (sel_ == SEL_PART) {
|
||||||
|
assert(msb_ && lsb_);
|
||||||
|
|
||||||
|
/* If the parameter has a part select, we support
|
||||||
|
it by pulling the right bits out and making a
|
||||||
|
sized unsigned constant. This code assumes the
|
||||||
|
lsb of a parameter is 0 and the msb is the
|
||||||
|
width of the parameter. */
|
||||||
|
|
||||||
|
verinum*lsn = lsb_->eval_const(des, scope);
|
||||||
|
verinum*msn = msb_->eval_const(des, scope);
|
||||||
|
if ((lsn == 0) || (msn == 0)) {
|
||||||
|
cerr << get_line() << ": error: "
|
||||||
|
"Part select expressions must be "
|
||||||
|
"constant expressions." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long lsb = lsn->as_long();
|
||||||
|
long msb = msn->as_long();
|
||||||
|
if ((lsb < 0) || (msb < lsb)) {
|
||||||
|
cerr << get_line() << ": error: invalid part "
|
||||||
|
<< "select: " << path_
|
||||||
|
<< "["<<msb<<":"<<lsb<<"]" << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
unsigned long ulsb=lsb;
|
||||||
|
unsigned long umsb=msb;
|
||||||
|
|
||||||
|
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
||||||
|
assert(le);
|
||||||
|
|
||||||
|
verinum result (verinum::V0, msb-lsb+1, true);
|
||||||
|
verinum exl = le->value();
|
||||||
|
|
||||||
|
/* Pull the bits from the parameter, one at a
|
||||||
|
time. If the bit is within the range, simply
|
||||||
|
copy it to the result. If the bit is outside
|
||||||
|
the range, we sign extend signed unsized
|
||||||
|
numbers, zero extend unsigned unsigned numbers,
|
||||||
|
and X extend sized numbers. */
|
||||||
|
for (unsigned long idx = ulsb ; idx <= umsb ; idx += 1) {
|
||||||
|
if (idx < exl.len())
|
||||||
|
result.set(idx-lsb, exl.get(idx));
|
||||||
|
else if (exl.is_string())
|
||||||
|
result.set(idx-lsb, verinum::V0);
|
||||||
|
else if (exl.has_len())
|
||||||
|
result.set(idx-lsb, verinum::Vx);
|
||||||
|
else if (exl.has_sign())
|
||||||
|
result.set(idx-lsb, exl.get(exl.len()-1));
|
||||||
|
else
|
||||||
|
result.set(idx-lsb, verinum::V0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the input is a string, and the part select
|
||||||
|
is working on byte boundaries, then the result
|
||||||
|
can be made into a string. */
|
||||||
|
if (exl.is_string()
|
||||||
|
&& (lsb%8 == 0)
|
||||||
|
&& (result.len()%8 == 0))
|
||||||
|
result = verinum(result.as_string());
|
||||||
|
|
||||||
|
delete tmp;
|
||||||
|
tmp = new NetEConst(result);
|
||||||
|
|
||||||
|
} else if (sel_ == SEL_IDX_UP || sel_ == SEL_IDX_DO) {
|
||||||
|
assert(msb_);
|
||||||
|
assert(lsb_);
|
||||||
|
|
||||||
|
/* Get and evaluate the width of the index
|
||||||
|
select. This must be constant. */
|
||||||
|
NetExpr*wid_ex = elab_and_eval(des, scope, lsb_);
|
||||||
|
NetEConst*wid_ec = dynamic_cast<NetEConst*> (wid_ex);
|
||||||
|
if (wid_ec == 0) {
|
||||||
|
cerr << lsb_->get_line() << ": error: "
|
||||||
|
<< "Second expression of indexed part select "
|
||||||
|
<< "most be constant." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned wid = wid_ec->value().as_ulong();
|
||||||
|
|
||||||
|
NetExpr*idx_ex = elab_and_eval(des, scope, msb_);
|
||||||
|
if (idx_ex == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sel_ == SEL_IDX_DO && wid > 1) {
|
||||||
|
idx_ex = make_add_expr(idx_ex, 1-(long)wid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrap the param expression with a part select. */
|
||||||
|
tmp = new NetESelect(tmp, idx_ex, wid);
|
||||||
|
|
||||||
|
|
||||||
|
} else if (msb_) {
|
||||||
|
/* Handle the case where a parameter has a bit
|
||||||
|
select attached to it. Generate a NetESelect
|
||||||
|
object to select the bit as desired. */
|
||||||
|
NetExpr*mtmp = msb_->elaborate_expr(des, scope);
|
||||||
|
if (! dynamic_cast<NetEConst*>(mtmp)) {
|
||||||
|
NetExpr*re = mtmp->eval_tree();
|
||||||
|
if (re) {
|
||||||
|
delete mtmp;
|
||||||
|
mtmp = re;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let's first try to get constant values for both
|
||||||
|
the parameter and the bit select. If they are
|
||||||
|
both constant, then evaluate the bit select and
|
||||||
|
return instead a single-bit constant. */
|
||||||
|
|
||||||
|
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
||||||
|
NetEConst*re = dynamic_cast<NetEConst*>(mtmp);
|
||||||
|
if (le && re) {
|
||||||
|
|
||||||
|
verinum lv = le->value();
|
||||||
|
verinum rv = re->value();
|
||||||
|
verinum::V rb = verinum::Vx;
|
||||||
|
|
||||||
|
long ridx = rv.as_long();
|
||||||
|
if ((ridx >= 0) && ((unsigned long) ridx < lv.len())) {
|
||||||
|
rb = lv[ridx];
|
||||||
|
|
||||||
|
} else if ((ridx >= 0) && (!lv.has_len())) {
|
||||||
|
if (lv.has_sign())
|
||||||
|
rb = lv[lv.len()-1];
|
||||||
|
else
|
||||||
|
rb = verinum::V0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetEConst*re = new NetEConst(verinum(rb, 1));
|
||||||
|
delete tmp;
|
||||||
|
delete mtmp;
|
||||||
|
tmp = re;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
NetESelect*stmp = new NetESelect(tmp, mtmp, 1);
|
||||||
|
tmp->set_line(*this);
|
||||||
|
tmp = stmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* No bit or part select. Make the constant into a
|
||||||
|
NetEConstParam if possible. */
|
||||||
|
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
|
||||||
|
if (ctmp != 0) {
|
||||||
|
perm_string name
|
||||||
|
= lex_strings.make(path_.peek_tail_name());
|
||||||
|
NetEConstParam*ptmp
|
||||||
|
= new NetEConstParam(found_in, name, ctmp->value());
|
||||||
|
delete tmp;
|
||||||
|
tmp = ptmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp->set_line(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const
|
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const
|
||||||
{
|
{
|
||||||
assert(value_);
|
assert(value_);
|
||||||
|
|
@ -1048,6 +1091,9 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_expr.cc,v $
|
* $Log: elab_expr.cc,v $
|
||||||
|
* Revision 1.98 2005/10/04 04:09:25 steve
|
||||||
|
* Add support for indexed select attached to parameters.
|
||||||
|
*
|
||||||
* Revision 1.97 2005/09/19 21:45:35 steve
|
* Revision 1.97 2005/09/19 21:45:35 steve
|
||||||
* Spelling patches from Larry.
|
* Spelling patches from Larry.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
40
parse.y
40
parse.y
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: parse.y,v 1.205 2005/07/27 14:54:51 steve Exp $"
|
#ident "$Id: parse.y,v 1.206 2005/10/04 04:09:25 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -988,15 +988,47 @@ expr_primary
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* There are 3 kinds of part selects. The basic part select has the
|
||||||
|
usual [M:L] syntax. The indexed part selects use +: or -: in
|
||||||
|
place of the : in the basic part select, and the first expression
|
||||||
|
is not limited to constant values. */
|
||||||
|
|
||||||
| identifier '[' expression ':' expression ']'
|
| identifier '[' expression ':' expression ']'
|
||||||
{ PEIdent*tmp = new PEIdent(*$1);
|
{ PEIdent*tmp = new PEIdent(*$1);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
tmp->msb_ = $3;
|
tmp->msb_ = $3;
|
||||||
tmp->lsb_ = $5;
|
tmp->lsb_ = $5;
|
||||||
|
tmp->sel_ = PEIdent::SEL_PART;
|
||||||
delete $1;
|
delete $1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
| identifier '[' expression K_PO_POS expression ']'
|
||||||
|
{ PEIdent*tmp = new PEIdent(*$1);
|
||||||
|
tmp->set_file(@1.text);
|
||||||
|
tmp->set_lineno(@1.first_line);
|
||||||
|
tmp->msb_ = $3;
|
||||||
|
tmp->lsb_ = $5;
|
||||||
|
tmp->sel_ = PEIdent::SEL_IDX_UP;
|
||||||
|
delete $1;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
| identifier '[' expression K_PO_NEG expression ']'
|
||||||
|
{ PEIdent*tmp = new PEIdent(*$1);
|
||||||
|
tmp->set_file(@1.text);
|
||||||
|
tmp->set_lineno(@1.first_line);
|
||||||
|
tmp->msb_ = $3;
|
||||||
|
tmp->lsb_ = $5;
|
||||||
|
tmp->sel_ = PEIdent::SEL_IDX_DO;
|
||||||
|
delete $1;
|
||||||
|
$$ = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An identifer followed by an expression list in parentheses is a
|
||||||
|
function call. If a system identifier, then a system function
|
||||||
|
call. */
|
||||||
|
|
||||||
| identifier '(' expression_list ')'
|
| identifier '(' expression_list ')'
|
||||||
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
|
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
|
|
@ -1010,8 +1042,14 @@ expr_primary
|
||||||
tmp->set_lineno(@1.first_line);
|
tmp->set_lineno(@1.first_line);
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parenthesized expressions are primaries. */
|
||||||
|
|
||||||
| '(' expression ')'
|
| '(' expression ')'
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
|
|
||||||
|
/* Various kinds of concatenation expressions. */
|
||||||
|
|
||||||
| '{' expression_list '}'
|
| '{' expression_list '}'
|
||||||
{ PEConcat*tmp = new PEConcat(*$2);
|
{ PEConcat*tmp = new PEConcat(*$2);
|
||||||
tmp->set_file(@1.text);
|
tmp->set_file(@1.text);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_CVS_IDENT
|
#ifdef HAVE_CVS_IDENT
|
||||||
#ident "$Id: pform_dump.cc,v 1.90 2005/07/11 16:56:51 steve Exp $"
|
#ident "$Id: pform_dump.cc,v 1.91 2005/10/04 04:09:26 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -145,8 +145,19 @@ void PEIdent::dump(ostream&out) const
|
||||||
out << path_;
|
out << path_;
|
||||||
if (msb_) {
|
if (msb_) {
|
||||||
out << "[" << *msb_;
|
out << "[" << *msb_;
|
||||||
if (lsb_) {
|
if (lsb_) switch (sel_) {
|
||||||
|
case SEL_IDX_UP:
|
||||||
|
out << "+:" << *lsb_;
|
||||||
|
break;
|
||||||
|
case SEL_IDX_DO:
|
||||||
|
out << "-:" << *lsb_;
|
||||||
|
break;
|
||||||
|
case SEL_PART:
|
||||||
out << ":" << *lsb_;
|
out << ":" << *lsb_;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out << ":?:" << *lsb_;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
out << "]";
|
out << "]";
|
||||||
}
|
}
|
||||||
|
|
@ -903,6 +914,9 @@ void PUdp::dump(ostream&out) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: pform_dump.cc,v $
|
* $Log: pform_dump.cc,v $
|
||||||
|
* Revision 1.91 2005/10/04 04:09:26 steve
|
||||||
|
* Add support for indexed select attached to parameters.
|
||||||
|
*
|
||||||
* Revision 1.90 2005/07/11 16:56:51 steve
|
* Revision 1.90 2005/07/11 16:56:51 steve
|
||||||
* Remove NetVariable and ivl_variable_t structures.
|
* Remove NetVariable and ivl_variable_t structures.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue