Blend new_darray and new_class expression nodes.

This commit is contained in:
Stephen Williams 2012-11-17 16:44:25 -08:00
parent 7a2ad01f2e
commit b6eb86d696
9 changed files with 95 additions and 27 deletions

View File

@ -4007,9 +4007,8 @@ NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
unsigned use_wid = size_->test_width(des, scope, mode);
NetExpr*size = size_->elaborate_expr(des, scope, use_wid, flags);
NetESFunc*tmp = new NetESFunc("$ivl_darray_method$new", ntype, 1);
NetENew*tmp = new NetENew(ntype, size);
tmp->set_line(*this);
tmp->parm(0, size);
return tmp;
}
@ -4019,14 +4018,8 @@ NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
NetExpr* PENew::elaborate_expr(Design*des, NetScope*scope,
unsigned, unsigned flags) const
{
width_mode_t mode = LOSSLESS;
unsigned use_wid = size_->test_width(des, scope, mode);
NetExpr*size = size_->elaborate_expr(des, scope, use_wid, flags);
NetESFunc*tmp = new NetESFunc("$ivl_darray_method$new",
IVL_VT_DARRAY, 1, 1);
tmp->set_line(*this);
tmp->parm(0, size);
return tmp;
ivl_assert(*this, 0);
return 0;
}
unsigned PENewClass::test_width(Design*, NetScope*, width_mode_t&)

View File

@ -322,7 +322,12 @@ netenum_t* NetENetenum::netenum() const
}
NetENew::NetENew(ivl_type_t t)
: obj_type_(t)
: obj_type_(t), size_(0)
{
}
NetENew::NetENew(ivl_type_t t, NetExpr*size)
: obj_type_(t), size_(size)
{
}
@ -330,6 +335,11 @@ NetENew::~NetENew()
{
}
ivl_variable_type_t NetENew::expr_type() const
{
return size_ ? IVL_VT_DARRAY : IVL_VT_CLASS;
}
NetENull::NetENull()
{
}

View File

@ -3879,10 +3879,16 @@ class NetENetenum : public NetExpr {
class NetENew : public NetExpr {
public:
// Make class object
explicit NetENew(ivl_type_t);
// dynamic array of objects.
explicit NetENew(ivl_type_t, NetExpr*);
~NetENew();
inline ivl_type_t get_type() const { return obj_type_; }
inline const NetExpr*size_expr() const { return size_; }
virtual ivl_variable_type_t expr_type() const;
virtual void expr_scan(struct expr_scan_t*) const;
virtual NetENew* dup_expr() const;
@ -3892,6 +3898,7 @@ class NetENew : public NetExpr {
private:
ivl_type_t obj_type_;
NetExpr*size_;
};
/*

View File

@ -472,6 +472,9 @@ extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
case IVL_EX_MEMORY:
return net->u_.memory_.idx_;
case IVL_EX_NEW:
return net->u_.new_.size;
case IVL_EX_SIGNAL:
return net->u_.signal_.word;

View File

@ -318,6 +318,13 @@ void dll_target::expr_creal(const NetECReal*net)
void dll_target::expr_new(const NetENew*net)
{
ivl_expr_t size = 0;
if (net->size_expr()) {
net->size_expr()->expr_scan(this);
size = expr_;
expr_ = 0;
}
assert(expr_ == 0);
expr_ = (ivl_expr_t)calloc(1, sizeof(struct ivl_expr_s));
expr_->width_ = net->expr_width();
@ -325,8 +332,9 @@ void dll_target::expr_new(const NetENew*net)
expr_->sized_ = 1;
expr_->type_ = IVL_EX_NEW;
FILE_NAME(expr_, net);
expr_->value_ = IVL_VT_CLASS;
expr_->value_ = net->expr_type(); // May be IVL_VT_DARRAY or _CLASS
expr_->net_type= net->get_type();
expr_->u_.new_.size = size;
}
void dll_target::expr_null(const NetENull*net)

View File

@ -320,6 +320,10 @@ struct ivl_expr_s {
uint64_t value;
} delay_;
struct {
ivl_expr_t size;
} new_;
} u_;
};

View File

@ -167,11 +167,31 @@ static void show_memory_expression(ivl_expr_t net, unsigned ind)
static void show_new_expression(ivl_expr_t net, unsigned ind)
{
fprintf(out, "%*snew <type>\n", ind, "");
if (ivl_expr_value(net) != IVL_VT_CLASS) {
fprintf(out, "%sERROR: new expression must be IVL_VT_CLASS, got %s.\n",
switch (ivl_expr_value(net)) {
case IVL_VT_CLASS:
fprintf(out, "%*snew <class_type>\n", ind, "");
if (ivl_expr_oper1(net)) {
fprintf(out, "%*sERROR: class_new expression has a size!\n",
ind+3, "");
show_expression(ivl_expr_oper1(net), ind+3);
stub_errors += 1;
}
break;
case IVL_VT_DARRAY:
fprintf(out, "%*snew [] <type>\n", ind, "");
if (ivl_expr_oper1(net)) {
show_expression(ivl_expr_oper1(net), ind+3);
} else {
fprintf(out, "%*sERROR: darray_new missing size expression\n",
ind+3, "");
stub_errors += 1;
}
break;
default:
fprintf(out, "%*snew ERROR: expression type: %s\n",
ind+3, "", vt_type_string(net));
stub_errors += 1;
break;
}
}
@ -179,7 +199,7 @@ static void show_null_expression(ivl_expr_t net, unsigned ind)
{
fprintf(out, "%*s<null>\n", ind, "");
if (ivl_expr_value(net) != IVL_VT_CLASS) {
fprintf(out, "%sERROR: null expression must be IVL_VT_CLASS, got %s.\n",
fprintf(out, "%*sERROR: null expression must be IVL_VT_CLASS, got %s.\n",
ind+3, "", vt_type_string(net));
stub_errors += 1;
}

View File

@ -24,7 +24,7 @@
static int eval_darray_new(ivl_expr_t ex)
{
unsigned size_reg = allocate_word();
ivl_expr_t size_expr = ivl_expr_parm(ex, 0);
ivl_expr_t size_expr = ivl_expr_oper1(ex);
draw_eval_expr_into_integer(size_expr, size_reg);
clr_word(size_reg);
@ -67,23 +67,27 @@ static int eval_darray_new(ivl_expr_t ex)
return 0;
}
static int draw_eval_object_sfunc(ivl_expr_t ex)
static int eval_class_new(ivl_expr_t ex)
{
const char*name = ivl_expr_name(ex);
if (strcmp(name, "$ivl_darray_method$new") == 0)
return eval_darray_new(ex);
fprintf(vvp_out, "; ERROR: Invalid system function %s for darray\n", name);
return 1;
fprintf(vvp_out, " %%new/cobj ; XXXX Need to specify the type?\n");
return 0;
}
int draw_eval_object(ivl_expr_t ex)
{
switch (ivl_expr_type(ex)) {
case IVL_EX_SFUNC:
return draw_eval_object_sfunc(ex);
case IVL_EX_NEW:
switch (ivl_expr_value(ex)) {
case IVL_VT_CLASS:
return eval_class_new(ex);
case IVL_VT_DARRAY:
return eval_darray_new(ex);
default:
fprintf(vvp_out, "; ERROR: Invalid type (%d) for <new>\n",
ivl_expr_value(ex));
return 0;
}
default:
fprintf(vvp_out, "; ERROR: Invalid expression type %u\n", ivl_expr_type(ex));
return 1;

View File

@ -811,6 +811,9 @@ static int show_stmt_assign_sig_darray(ivl_statement_t net)
if (rvec.base >= 4) clr_vector(rvec);
} else {
/* There is no l-value mux, so this must be an
assignment to the array as a whole. Evaluate the
"object", and store the evaluated result. */
errors += draw_eval_object(rval);
fprintf(vvp_out, " %%store/obj v%p_0;\n", var);
}
@ -818,6 +821,18 @@ static int show_stmt_assign_sig_darray(ivl_statement_t net)
return errors;
}
static int show_stmt_assign_sig_cobject(ivl_statement_t net)
{
int errors = 0;
ivl_lval_t lval = ivl_stmt_lval(net, 0);
ivl_expr_t rval = ivl_stmt_rval(net);
ivl_signal_t var= ivl_lval_sig(lval);
errors += draw_eval_object(rval);
fprintf(vvp_out, " %%store/obj v%p_0;\n", var);
return errors;
}
int show_stmt_assign(ivl_statement_t net)
{
ivl_lval_t lval;
@ -840,5 +855,9 @@ int show_stmt_assign(ivl_statement_t net)
return show_stmt_assign_sig_darray(net);
}
if (sig && (ivl_signal_data_type(sig) == IVL_VT_CLASS)) {
return show_stmt_assign_sig_cobject(net);
}
return show_stmt_assign_vector(net);
}