Generate code to implement new element initializers.
This commit is contained in:
parent
3945b9df45
commit
82ebf6372c
2
PExpr.h
2
PExpr.h
|
|
@ -302,6 +302,8 @@ class PEFNumber : public PExpr {
|
|||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
|
|
|||
|
|
@ -2537,6 +2537,13 @@ unsigned PEFNumber::test_width(Design*, NetScope*, width_mode_t&)
|
|||
return expr_width_;
|
||||
}
|
||||
|
||||
NetExpr* PEFNumber::elaborate_expr(Design*, NetScope*, ivl_type_t type, unsigned) const
|
||||
{
|
||||
NetECReal*tmp = new NetECReal(*value_);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEFNumber::elaborate_expr(Design*, NetScope*, unsigned, unsigned) const
|
||||
{
|
||||
NetECReal*tmp = new NetECReal(*value_);
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@
|
|||
|
||||
static int eval_darray_new(ivl_expr_t ex)
|
||||
{
|
||||
int errors = 0;
|
||||
unsigned size_reg = allocate_word();
|
||||
ivl_expr_t size_expr = ivl_expr_oper1(ex);
|
||||
ivl_expr_t init_expr = ivl_expr_oper2(ex);
|
||||
draw_eval_expr_into_integer(size_expr, size_reg);
|
||||
clr_word(size_reg);
|
||||
|
||||
|
|
@ -64,7 +66,41 @@ static int eval_darray_new(ivl_expr_t ex)
|
|||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (init_expr && ivl_expr_type(init_expr)==IVL_EX_ARRAY_PATTERN) {
|
||||
int idx;
|
||||
struct vector_info rvec;
|
||||
unsigned wid;
|
||||
switch (ivl_type_base(element_type)) {
|
||||
case IVL_VT_BOOL:
|
||||
wid = width_of_packed_type(element_type);
|
||||
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
|
||||
rvec = draw_eval_expr_wid(ivl_expr_parm(init_expr,idx),
|
||||
wid, STUFF_OK_XZ);
|
||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||
fprintf(vvp_out, " %%set/dar/obj 3, %u, %u;\n",
|
||||
rvec.base, rvec.wid);
|
||||
if (rvec.base >= 4) clr_vector(rvec);
|
||||
}
|
||||
break;
|
||||
case IVL_VT_REAL:
|
||||
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
|
||||
draw_eval_real(ivl_expr_parm(init_expr,idx));
|
||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||
fprintf(vvp_out, " %%set/dar/obj/real 3;\n");
|
||||
fprintf(vvp_out, " %%pop/real 1;\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
|
||||
errors += 1;
|
||||
break;
|
||||
}
|
||||
} else if (init_expr) {
|
||||
fprintf(vvp_out, "; ERROR: Init_expr not supported here\n");
|
||||
errors += 1;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
static int eval_class_new(ivl_expr_t ex)
|
||||
|
|
|
|||
|
|
@ -687,7 +687,7 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
|||
}
|
||||
|
||||
/*
|
||||
* This function assigns a value to a real .variable. This is destined
|
||||
* This function assigns a value to a real variable. This is destined
|
||||
* for /dev/null when typed ivl_signal_t takes over all the real
|
||||
* variable support.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ extern bool of_RELEASE_WR(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_SCOPY(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_AV(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_DAR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_DAR_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_VEC(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_X0(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SET_X0_X(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -229,6 +229,8 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%scopy", of_SCOPY, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%set/av", of_SET_AV, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%set/dar",of_SET_DAR,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%set/dar/obj", of_SET_DAR_OBJ, 3,{OA_NUMBER,OA_BIT1,OA_BIT2} },
|
||||
{ "%set/dar/obj/real",of_SET_DAR_OBJ_REAL,1,{OA_NUMBER,OA_NONE,OA_NONE} },
|
||||
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%set/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },
|
||||
|
|
|
|||
|
|
@ -952,10 +952,21 @@ statement. The <type> is 0 for nets and 1 for registers. See the other
|
|||
%release commands above.
|
||||
|
||||
* %set/dar <var-label>, <bit>, <wid>
|
||||
* %set/dar/obj <index>, <bit>, <wid>
|
||||
|
||||
This sets a vector to a word of the dynamic array. Index register 3
|
||||
contains the word address within the dynamic array, and <bit>,<wid>
|
||||
specifies the thread vector to be written.
|
||||
The "%set/dar" opcode sets a vector to a word of the dynamic
|
||||
array. Index register 3 contains the word address within the dynamic
|
||||
array, and <bit>,<wid> specifies the thread vector to be written.
|
||||
|
||||
The "%set/dar/obj" opcode is similar, except that it sets elements of
|
||||
a dynamic array that is in the top of the object stack. Instead of
|
||||
using a fixed index register, use the register addressed by <index>.
|
||||
|
||||
* %set/dar/obj/real <index>
|
||||
|
||||
The "%set/dar/obj/real" opcode sets the top value from the real-value
|
||||
stack to the index. This does NOT pop the real value off the
|
||||
stack. The intent is that this value may be written to a bunch of values.
|
||||
|
||||
* %set/v <var-label>, <bit>, <wid>
|
||||
|
||||
|
|
|
|||
|
|
@ -4921,6 +4921,42 @@ bool of_SET_DAR(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %set/dar/obj <index>, <bit>, <wid>
|
||||
*/
|
||||
bool of_SET_DAR_OBJ(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned adr = thr->words[cp->number].w_int;
|
||||
unsigned bit = cp->bit_idx[0];
|
||||
unsigned wid = cp->bit_idx[1];
|
||||
|
||||
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
|
||||
|
||||
vvp_object_t&top = thr->peek_object();
|
||||
vvp_darray*darray = top.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
|
||||
darray->set_word(adr, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %set/dar/obj/real <index>
|
||||
*/
|
||||
bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned adr = thr->words[cp->number].w_int;
|
||||
|
||||
double value = thr->peek_real(0);
|
||||
|
||||
vvp_object_t&top = thr->peek_object();
|
||||
vvp_darray*darray = top.peek<vvp_darray>();
|
||||
assert(darray);
|
||||
|
||||
darray->set_word(adr, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This implements the "%set/v <label>, <bit>, <wid>" instruction.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue