Rework parse of compression assignments.

This commit is contained in:
Stephen Williams 2011-11-27 11:16:39 -08:00
parent 5e9e309be8
commit cc9bbff78d
4 changed files with 99 additions and 86 deletions

View File

@ -51,22 +51,27 @@ PAssign_::~PAssign_()
} }
PAssign::PAssign(PExpr*lval__, PExpr*ex) PAssign::PAssign(PExpr*lval__, PExpr*ex)
: PAssign_(lval__, ex, false) : PAssign_(lval__, ex, false), op_(0)
{
}
PAssign::PAssign(PExpr*lval__, char op, PExpr*ex)
: PAssign_(lval__, ex, false), op_(op)
{ {
} }
PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex) PAssign::PAssign(PExpr*lval__, PExpr*d, PExpr*ex)
: PAssign_(lval__, d, ex) : PAssign_(lval__, d, ex), op_(0)
{ {
} }
PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex) PAssign::PAssign(PExpr*lval__, PExpr*cnt, PEventStatement*d, PExpr*ex)
: PAssign_(lval__, cnt, d, ex) : PAssign_(lval__, cnt, d, ex), op_(0)
{ {
} }
PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant) PAssign::PAssign(PExpr*lval__, PExpr*ex, bool is_constant)
: PAssign_(lval__, ex, is_constant) : PAssign_(lval__, ex, is_constant), op_(0)
{ {
} }

View File

@ -120,7 +120,12 @@ class PAssign_ : public Statement {
class PAssign : public PAssign_ { class PAssign : public PAssign_ {
public: public:
// lval - assignment l-value
// ex - assignment r-value
// op - compressed assignment operator (i.e. '+', '-', ...)
// de - delayed assignment delay expression
explicit PAssign(PExpr*lval, PExpr*ex); explicit PAssign(PExpr*lval, PExpr*ex);
explicit PAssign(PExpr*lval, char op, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex); explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex); explicit PAssign(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant); explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant);
@ -130,6 +135,8 @@ class PAssign : public PAssign_ {
virtual NetProc* elaborate(Design*des, NetScope*scope) const; virtual NetProc* elaborate(Design*des, NetScope*scope) const;
private: private:
NetProc* elaborate_compressed_(Design*des, NetScope*scope) const;
char op_;
}; };
class PAssignNB : public PAssign_ { class PAssignNB : public PAssign_ {

View File

@ -2259,10 +2259,33 @@ static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
return dex; return dex;
} }
NetProc* PAssign::elaborate_compressed_(Design*des, NetScope*scope) const
{
ivl_assert(*this, ! delay_);
ivl_assert(*this, ! count_);
ivl_assert(*this, ! event_);
NetAssign_*lv = elaborate_lval(des, scope);
if (lv == 0) return 0;
NetExpr*rv = elaborate_rval_(des, scope, count_lval_width(lv), lv->expr_type());
if (rv == 0) return 0;
NetAssign*cur = new NetAssign(lv, rv);
cur->set_line(*this);
return cur;
}
NetProc* PAssign::elaborate(Design*des, NetScope*scope) const NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
{ {
assert(scope); assert(scope);
/* If this is a compressed assignment, then handle the
elaboration in a specialized function. */
if (op_ != 0)
return elaborate_compressed_(des, scope);
/* elaborate the lval. This detects any part selects and mux /* elaborate the lval. This detects any part selects and mux
expressions that might exist. */ expressions that might exist. */
NetAssign_*lv = elaborate_lval(des, scope); NetAssign_*lv = elaborate_lval(des, scope);

44
parse.y
View File

@ -4664,79 +4664,57 @@ statement
compressed_statement compressed_statement
: lpvalue K_PLUS_EQ expression : lpvalue K_PLUS_EQ expression
{ { PAssign*tmp = new PAssign($1, '+', $3);
PEBinary *t = new PEBinary('+', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_MINUS_EQ expression | lpvalue K_MINUS_EQ expression
{ { PAssign*tmp = new PAssign($1, '-', $3);
PEBinary *t = new PEBinary('-', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_MUL_EQ expression | lpvalue K_MUL_EQ expression
{ { PAssign*tmp = new PAssign($1, '*', $3);
PEBinary *t = new PEBinary('*', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_DIV_EQ expression | lpvalue K_DIV_EQ expression
{ { PAssign*tmp = new PAssign($1, '/', $3);
PEBinary *t = new PEBinary('/', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_MOD_EQ expression | lpvalue K_MOD_EQ expression
{ { PAssign*tmp = new PAssign($1, '%', $3);
PEBinary *t = new PEBinary('%', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_AND_EQ expression | lpvalue K_AND_EQ expression
{ { PAssign*tmp = new PAssign($1, '&', $3);
PEBinary *t = new PEBinary('&', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_OR_EQ expression | lpvalue K_OR_EQ expression
{ { PAssign*tmp = new PAssign($1, '|', $3);
PEBinary *t = new PEBinary('|', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_XOR_EQ expression | lpvalue K_XOR_EQ expression
{ { PAssign*tmp = new PAssign($1, '^', $3);
PEBinary *t = new PEBinary('^', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_LS_EQ expression | lpvalue K_LS_EQ expression
{ { PAssign *tmp = new PAssign($1, 'l', $3);
PEBShift *t = new PEBShift('l', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_RS_EQ expression | lpvalue K_RS_EQ expression
{ { PAssign*tmp = new PAssign($1, 'r', $3);
PEBShift *t = new PEBShift('r', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }
| lpvalue K_RSS_EQ expression | lpvalue K_RSS_EQ expression
{ { PAssign *tmp = new PAssign($1, 'R', $3);
PEBShift *t = new PEBShift('R', $1, $3);
PAssign *tmp = new PAssign($1, t);
FILE_NAME(tmp, @1); FILE_NAME(tmp, @1);
$$ = tmp; $$ = tmp;
} }