Generate vvp code for case statements.
This commit is contained in:
parent
2f1d258acb
commit
b3a3b888d8
16
ivl_target.h
16
ivl_target.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: ivl_target.h,v 1.39 2001/03/30 05:49:52 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.40 2001/03/31 17:36:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -247,6 +247,9 @@ typedef enum ivl_statement_type_e {
|
|||
IVL_ST_NOOP = 1,
|
||||
IVL_ST_ASSIGN,
|
||||
IVL_ST_BLOCK,
|
||||
IVL_ST_CASE,
|
||||
IVL_ST_CASEX,
|
||||
IVL_ST_CASEZ,
|
||||
IVL_ST_CONDIT,
|
||||
IVL_ST_DELAY,
|
||||
IVL_ST_DELAYX,
|
||||
|
|
@ -676,7 +679,13 @@ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net);
|
|||
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
||||
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_CONDIT */
|
||||
/* IVL_ST_CASE */
|
||||
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
|
||||
/* IVL_ST_CASE */
|
||||
extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_CASE */
|
||||
extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_CONDIT, IVL_ST_CASE */
|
||||
extern ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net);
|
||||
/* IVL_ST_CONDIT */
|
||||
extern ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net);
|
||||
|
|
@ -721,6 +730,9 @@ _END_DECL
|
|||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.40 2001/03/31 17:36:38 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.39 2001/03/30 05:49:52 steve
|
||||
* Generate code for fork/join statements.
|
||||
*
|
||||
|
|
|
|||
63
t-dll-api.cc
63
t-dll-api.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll-api.cc,v 1.27 2001/03/30 05:49:52 steve Exp $"
|
||||
#ident "$Id: t-dll-api.cc,v 1.28 2001/03/31 17:36:38 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "t-dll.h"
|
||||
|
|
@ -580,10 +580,64 @@ extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net,
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net)
|
||||
{
|
||||
switch (net->type_) {
|
||||
case IVL_ST_CASE:
|
||||
case IVL_ST_CASEX:
|
||||
case IVL_ST_CASEZ:
|
||||
return net->u_.case_.ncase;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned idx)
|
||||
{
|
||||
switch (net->type_) {
|
||||
case IVL_ST_CASE:
|
||||
case IVL_ST_CASEX:
|
||||
case IVL_ST_CASEZ:
|
||||
assert(idx < net->u_.case_.ncase);
|
||||
return net->u_.case_.case_ex[idx];
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned idx)
|
||||
{
|
||||
switch (net->type_) {
|
||||
case IVL_ST_CASE:
|
||||
case IVL_ST_CASEX:
|
||||
case IVL_ST_CASEZ:
|
||||
assert(idx < net->u_.case_.ncase);
|
||||
return net->u_.case_.case_st + idx;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net)
|
||||
{
|
||||
assert(net && (net->type_ == IVL_ST_CONDIT));
|
||||
return net->u_.condit_.cond_;
|
||||
switch (net->type_) {
|
||||
case IVL_ST_CONDIT:
|
||||
return net->u_.condit_.cond_;
|
||||
|
||||
case IVL_ST_CASE:
|
||||
case IVL_ST_CASEX:
|
||||
case IVL_ST_CASEZ:
|
||||
return net->u_.case_.cond;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net)
|
||||
|
|
@ -727,6 +781,9 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
|
|||
|
||||
/*
|
||||
* $Log: t-dll-api.cc,v $
|
||||
* Revision 1.28 2001/03/31 17:36:38 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.27 2001/03/30 05:49:52 steve
|
||||
* Generate code for fork/join statements.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll-proc.cc,v 1.16 2001/03/30 23:24:02 steve Exp $"
|
||||
#ident "$Id: t-dll-proc.cc,v 1.17 2001/03/31 17:36:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -177,6 +177,54 @@ bool dll_target::proc_block(const NetBlock*net)
|
|||
return flag;
|
||||
}
|
||||
|
||||
void dll_target::proc_case(const NetCase*net)
|
||||
{
|
||||
assert(stmt_cur_);
|
||||
assert(stmt_cur_->type_ == IVL_ST_NONE);
|
||||
|
||||
switch (net->type()) {
|
||||
case NetCase::EQ:
|
||||
stmt_cur_->type_ = IVL_ST_CASE;
|
||||
break;
|
||||
case NetCase::EQX:
|
||||
stmt_cur_->type_ = IVL_ST_CASEX;
|
||||
break;
|
||||
case NetCase::EQZ:
|
||||
stmt_cur_->type_ = IVL_ST_CASEZ;
|
||||
break;
|
||||
}
|
||||
assert(stmt_cur_->type_ != IVL_ST_NONE);
|
||||
|
||||
assert(expr_ == 0);
|
||||
net->expr()->expr_scan(this);
|
||||
stmt_cur_->u_.case_.cond = expr_;
|
||||
expr_ = 0;
|
||||
|
||||
unsigned ncase = net->nitems();
|
||||
stmt_cur_->u_.case_.ncase = ncase;
|
||||
|
||||
stmt_cur_->u_.case_.case_ex = new ivl_expr_t[ncase];
|
||||
stmt_cur_->u_.case_.case_st = new struct ivl_statement_s[ncase];
|
||||
|
||||
ivl_statement_t save_cur = stmt_cur_;
|
||||
|
||||
for (unsigned idx = 0 ; idx < ncase ; idx += 1) {
|
||||
const NetExpr*ex = net->expr(idx);
|
||||
if (ex) {
|
||||
net->expr(idx)->expr_scan(this);
|
||||
save_cur->u_.case_.case_ex[idx] = expr_;
|
||||
expr_ = 0;
|
||||
} else {
|
||||
save_cur->u_.case_.case_ex[idx] = 0;
|
||||
}
|
||||
|
||||
stmt_cur_ = save_cur->u_.case_.case_st + idx;
|
||||
net->stat(idx)->emit_proc(this);
|
||||
}
|
||||
|
||||
stmt_cur_ = save_cur;
|
||||
}
|
||||
|
||||
void dll_target::proc_condit(const NetCondit*net)
|
||||
{
|
||||
assert(stmt_cur_);
|
||||
|
|
@ -364,6 +412,9 @@ void dll_target::proc_while(const NetWhile*net)
|
|||
|
||||
/*
|
||||
* $Log: t-dll-proc.cc,v $
|
||||
* Revision 1.17 2001/03/31 17:36:39 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.16 2001/03/30 23:24:02 steve
|
||||
* Make empty event sub-expression a noop.
|
||||
*
|
||||
|
|
|
|||
13
t-dll.h
13
t-dll.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: t-dll.h,v 1.27 2001/03/30 05:49:52 steve Exp $"
|
||||
#ident "$Id: t-dll.h,v 1.28 2001/03/31 17:36:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "target.h"
|
||||
|
|
@ -79,6 +79,7 @@ struct dll_target : public target_t, public expr_scan_t {
|
|||
struct ivl_statement_s*stmt_cur_;
|
||||
void proc_assign(const NetAssign*);
|
||||
bool proc_block(const NetBlock*);
|
||||
void proc_case(const NetCase*);
|
||||
void proc_condit(const NetCondit*);
|
||||
bool proc_delay(const NetPDelay*);
|
||||
void proc_stask(const NetSTask*);
|
||||
|
|
@ -346,6 +347,13 @@ struct ivl_statement_s {
|
|||
unsigned nstmt_;
|
||||
} block_;
|
||||
|
||||
struct { /* IVL_ST_CASE, IVL_ST_CASEX, IVL_ST_CASEZ */
|
||||
ivl_expr_t cond;
|
||||
unsigned ncase;
|
||||
ivl_expr_t*case_ex;
|
||||
struct ivl_statement_s*case_st;
|
||||
} case_;
|
||||
|
||||
struct { /* IVL_ST_CONDIT */
|
||||
/* This is the condition expression */
|
||||
ivl_expr_t cond_;
|
||||
|
|
@ -387,6 +395,9 @@ struct ivl_statement_s {
|
|||
|
||||
/*
|
||||
* $Log: t-dll.h,v $
|
||||
* Revision 1.28 2001/03/31 17:36:39 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.27 2001/03/30 05:49:52 steve
|
||||
* Generate code for fork/join statements.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: stub.c,v 1.32 2001/03/30 05:49:52 steve Exp $"
|
||||
#ident "$Id: stub.c,v 1.33 2001/03/31 17:36:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -164,6 +164,29 @@ static void show_statement(ivl_statement_t net, unsigned ind)
|
|||
break;
|
||||
}
|
||||
|
||||
case IVL_ST_CASEX:
|
||||
case IVL_ST_CASEZ:
|
||||
case IVL_ST_CASE: {
|
||||
unsigned cnt = ivl_stmt_case_count(net);
|
||||
unsigned idx;
|
||||
fprintf(out, "%*scase (...) <%u cases>\n", ind, "", cnt);
|
||||
show_expression(ivl_stmt_cond_expr(net), ind+4);
|
||||
|
||||
for (idx = 0 ; idx < cnt ; idx += 1) {
|
||||
ivl_expr_t ex = ivl_stmt_case_expr(net, idx);
|
||||
ivl_statement_t st = ivl_stmt_case_stmt(net, idx);
|
||||
if (ex == 0)
|
||||
fprintf(out, "%*sdefault\n", ind+4, "");
|
||||
else
|
||||
show_expression(ex, ind+4);
|
||||
|
||||
show_statement(st, ind+4);
|
||||
}
|
||||
|
||||
fprintf(out, "%*sendcase\n", ind, "");
|
||||
break;
|
||||
}
|
||||
|
||||
case IVL_ST_CONDIT: {
|
||||
ivl_statement_t t = ivl_stmt_cond_true(net);
|
||||
ivl_statement_t f = ivl_stmt_cond_false(net);
|
||||
|
|
@ -460,6 +483,9 @@ DECLARE_CYGWIN_DLL(DllMain);
|
|||
|
||||
/*
|
||||
* $Log: stub.c,v $
|
||||
* Revision 1.33 2001/03/31 17:36:39 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.32 2001/03/30 05:49:52 steve
|
||||
* Generate code for fork/join statements.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: eval_expr.c,v 1.6 2001/03/31 02:00:44 steve Exp $"
|
||||
#ident "$Id: eval_expr.c,v 1.7 2001/03/31 17:36:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -48,7 +48,7 @@ static inline void clr_bit(unsigned addr)
|
|||
allocation_map[addr] &= ~(1 << bit);
|
||||
}
|
||||
|
||||
static inline void clr_vector(struct vector_info vec)
|
||||
void clr_vector(struct vector_info vec)
|
||||
{
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < vec.wid ; idx += 1)
|
||||
|
|
@ -400,6 +400,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
|
|||
|
||||
/*
|
||||
* $Log: eval_expr.c,v $
|
||||
* Revision 1.7 2001/03/31 17:36:39 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.6 2001/03/31 02:00:44 steve
|
||||
* Generate code for + and concat expressions.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vvp_priv.h,v 1.5 2001/03/27 06:27:41 steve Exp $"
|
||||
#ident "$Id: vvp_priv.h,v 1.6 2001/03/31 17:36:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "ivl_target.h"
|
||||
|
|
@ -52,6 +52,12 @@ extern void draw_nexus_input(ivl_nexus_t nex);
|
|||
/*
|
||||
* The draw_eval_expr function writes out the code to evaluate a
|
||||
* behavioral expression.
|
||||
*
|
||||
* Expression results are placed into a vector allocated in the bit
|
||||
* space of the thread. The vector_info structure represents that
|
||||
* allocation. When the caller is done with the bits, it must release
|
||||
* the vector with clr_vector so that the code generator can reuse
|
||||
* those bits.
|
||||
*/
|
||||
struct vector_info {
|
||||
unsigned short base;
|
||||
|
|
@ -59,9 +65,15 @@ struct vector_info {
|
|||
};
|
||||
|
||||
extern struct vector_info draw_eval_expr(ivl_expr_t exp);
|
||||
extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w);
|
||||
|
||||
extern void clr_vector(struct vector_info vec);
|
||||
|
||||
/*
|
||||
* $Log: vvp_priv.h,v $
|
||||
* Revision 1.6 2001/03/31 17:36:39 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.5 2001/03/27 06:27:41 steve
|
||||
* Generate code for simple @ statements.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: vvp_process.c,v 1.12 2001/03/30 05:49:53 steve Exp $"
|
||||
#ident "$Id: vvp_process.c,v 1.13 2001/03/31 17:36:39 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "vvp_priv.h"
|
||||
|
|
@ -133,6 +133,77 @@ static int show_stmt_assign(ivl_statement_t net)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int show_stmt_case(ivl_statement_t net)
|
||||
{
|
||||
ivl_expr_t exp = ivl_stmt_cond_expr(net);
|
||||
struct vector_info cond = draw_eval_expr(exp);
|
||||
unsigned count = ivl_stmt_case_count(net);
|
||||
|
||||
unsigned local_base = local_count;
|
||||
|
||||
unsigned idx, default_case;
|
||||
|
||||
local_count += count + 1;
|
||||
|
||||
/* First draw the branch table. All the non-default cases
|
||||
generate a branch out of here, to the code that implements
|
||||
the case. The default will fall through all the tests. */
|
||||
default_case = count;
|
||||
|
||||
for (idx = 0 ; idx < count ; idx += 1) {
|
||||
ivl_expr_t cex = ivl_stmt_case_expr(net, idx);
|
||||
struct vector_info cvec;
|
||||
|
||||
if (cex == 0) {
|
||||
default_case = idx;
|
||||
continue;
|
||||
}
|
||||
|
||||
cvec = draw_eval_expr_wid(cex, cond.wid);
|
||||
|
||||
fprintf(vvp_out, " %%cmp/u %u, %u, %u;\n", cond.base,
|
||||
cvec.base, cond.wid);
|
||||
fprintf(vvp_out, " %%jmp/1 T_%d.%d, 6;\n",
|
||||
thread_count, local_base+idx);
|
||||
|
||||
|
||||
/* Done with the case expression */
|
||||
clr_vector(cvec);
|
||||
}
|
||||
|
||||
/* Done with the condition expression */
|
||||
clr_vector(cond);
|
||||
|
||||
/* Emit code for the default case. */
|
||||
if (default_case < count) {
|
||||
ivl_statement_t cst = ivl_stmt_case_stmt(net, default_case);
|
||||
show_statement(cst);
|
||||
}
|
||||
|
||||
/* Jump to the out of the case. */
|
||||
fprintf(vvp_out, " %%jmp T_%d.%d;\n", thread_count,
|
||||
local_base+count);
|
||||
|
||||
for (idx = 0 ; idx < count ; idx += 1) {
|
||||
ivl_statement_t cst = ivl_stmt_case_stmt(net, idx);
|
||||
|
||||
if (idx == default_case)
|
||||
continue;
|
||||
|
||||
fprintf(vvp_out, "T_%d.%d\n", thread_count, local_base+idx);
|
||||
show_statement(cst);
|
||||
|
||||
fprintf(vvp_out, " %%jmp T_%d.%d;\n", thread_count,
|
||||
local_base+count);
|
||||
|
||||
}
|
||||
|
||||
/* The out of the case. */
|
||||
fprintf(vvp_out, "T_%d.%d\n", thread_count, local_base+count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int show_stmt_condit(ivl_statement_t net)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -307,6 +378,10 @@ static int show_statement(ivl_statement_t net)
|
|||
break;
|
||||
}
|
||||
|
||||
case IVL_ST_CASE:
|
||||
rc += show_stmt_case(net);
|
||||
break;
|
||||
|
||||
case IVL_ST_CONDIT:
|
||||
rc += show_stmt_condit(net);
|
||||
break;
|
||||
|
|
@ -394,6 +469,9 @@ int draw_process(ivl_process_t net, void*x)
|
|||
|
||||
/*
|
||||
* $Log: vvp_process.c,v $
|
||||
* Revision 1.13 2001/03/31 17:36:39 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.12 2001/03/30 05:49:53 steve
|
||||
* Generate code for fork/join statements.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue