Handle initialized darray of strings
This includes adding support for returning strings from functions, adding initializing new darray with array_pattern strings, and assigning an array_pattern of strings to a preallocated darray. Also fix up support for initializing array with simple string expression.
This commit is contained in:
parent
d5a0f2fc07
commit
e60804cf41
3
PExpr.h
3
PExpr.h
|
|
@ -632,6 +632,9 @@ class PEString : public PExpr {
|
||||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||||
width_mode_t&mode);
|
width_mode_t&mode);
|
||||||
|
|
||||||
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
|
||||||
|
ivl_type_t type, unsigned flags) const;
|
||||||
|
|
||||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||||
unsigned expr_wid, unsigned) const;
|
unsigned expr_wid, unsigned) const;
|
||||||
verinum* eval_const(Design*, NetScope*) const;
|
verinum* eval_const(Design*, NetScope*) const;
|
||||||
|
|
|
||||||
10
elab_expr.cc
10
elab_expr.cc
|
|
@ -4898,6 +4898,16 @@ unsigned PEString::test_width(Design*, NetScope*, width_mode_t&)
|
||||||
return expr_width_;
|
return expr_width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetEConst* PEString::elaborate_expr(Design*, NetScope*, ivl_type_t type, unsigned)const
|
||||||
|
{
|
||||||
|
verinum val(value());
|
||||||
|
NetEConst*tmp = new NetEConst(val);
|
||||||
|
tmp->cast_signed(signed_flag_);
|
||||||
|
tmp->set_line(*this);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
NetEConst* PEString::elaborate_expr(Design*, NetScope*,
|
NetEConst* PEString::elaborate_expr(Design*, NetScope*,
|
||||||
unsigned expr_wid, unsigned) const
|
unsigned expr_wid, unsigned) const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,23 @@ void draw_ufunc_real(ivl_expr_t expr)
|
||||||
fprintf(vvp_out, " %%load/real v%p_0;\n", retval);
|
fprintf(vvp_out, " %%load/real v%p_0;\n", retval);
|
||||||
|
|
||||||
draw_ufunc_epilogue(expr);
|
draw_ufunc_epilogue(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_ufunc_string(ivl_expr_t expr)
|
||||||
|
{
|
||||||
|
ivl_scope_t def = ivl_expr_def(expr);
|
||||||
|
ivl_signal_t retval = ivl_scope_port(def, 0);
|
||||||
|
|
||||||
|
/* Take in arguments to function and call the function code. */
|
||||||
|
draw_ufunc_preamble(expr);
|
||||||
|
|
||||||
|
/* Return value signal cannot be an array. */
|
||||||
|
assert(ivl_signal_dimensions(retval) == 0);
|
||||||
|
|
||||||
|
/* Load the result into a word. */
|
||||||
|
fprintf(vvp_out, " %%load/str v%p_0;\n", retval);
|
||||||
|
|
||||||
|
draw_ufunc_epilogue(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_ufunc_object(ivl_expr_t expr)
|
void draw_ufunc_object(ivl_expr_t expr)
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,14 @@ static int eval_darray_new(ivl_expr_t ex)
|
||||||
fprintf(vvp_out, " %%pop/real 1;\n");
|
fprintf(vvp_out, " %%pop/real 1;\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IVL_VT_STRING:
|
||||||
|
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
|
||||||
|
draw_eval_string(ivl_expr_parm(init_expr,idx));
|
||||||
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%set/dar/obj/str 3;\n");
|
||||||
|
fprintf(vvp_out, " %%pop/str 1;\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
|
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
|
||||||
errors += 1;
|
errors += 1;
|
||||||
|
|
@ -123,6 +131,14 @@ static int eval_darray_new(ivl_expr_t ex)
|
||||||
}
|
}
|
||||||
fprintf(vvp_out, " %%pop/real 1;\n");
|
fprintf(vvp_out, " %%pop/real 1;\n");
|
||||||
break;
|
break;
|
||||||
|
case IVL_VT_STRING:
|
||||||
|
draw_eval_string(init_expr);
|
||||||
|
for (idx = 0 ; idx < cnt ; idx += 1) {
|
||||||
|
fprintf(vvp_out, " %%ix/load 3, %ld, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%set/dar/obj/str 3;\n");
|
||||||
|
}
|
||||||
|
fprintf(vvp_out, " %%pop/str 1;\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
|
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
|
||||||
errors += 1;
|
errors += 1;
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,10 @@ void draw_eval_string(ivl_expr_t expr)
|
||||||
fallback_eval(expr);
|
fallback_eval(expr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IVL_EX_UFUNC:
|
||||||
|
draw_ufunc_string(expr);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fallback_eval(expr);
|
fallback_eval(expr);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -853,6 +853,13 @@ static int show_stmt_assign_darray_pattern(ivl_statement_t net)
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
fprintf(vvp_out, " %%store/dar/r v%p_0;\n", var);
|
fprintf(vvp_out, " %%store/dar/r v%p_0;\n", var);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IVL_VT_STRING:
|
||||||
|
draw_eval_string(ivl_expr_parm(rval,idx));
|
||||||
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(vvp_out, "; ERROR: show_stmt_assign_darray_pattern: type_base=%d not implemented\n", ivl_type_base(element_type));
|
fprintf(vvp_out, "; ERROR: show_stmt_assign_darray_pattern: type_base=%d not implemented\n", ivl_type_base(element_type));
|
||||||
errors += 1;
|
errors += 1;
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ extern void draw_lpm_mux(ivl_lpm_t net);
|
||||||
|
|
||||||
extern struct vector_info draw_ufunc_expr(ivl_expr_t expr, unsigned wid);
|
extern struct vector_info draw_ufunc_expr(ivl_expr_t expr, unsigned wid);
|
||||||
extern void draw_ufunc_real(ivl_expr_t expr);
|
extern void draw_ufunc_real(ivl_expr_t expr);
|
||||||
|
extern void draw_ufunc_string(ivl_expr_t expr);
|
||||||
extern void draw_ufunc_object(ivl_expr_t expr);
|
extern void draw_ufunc_object(ivl_expr_t expr);
|
||||||
|
|
||||||
extern void pad_expr_in_place(ivl_expr_t expr, struct vector_info res,
|
extern void pad_expr_in_place(ivl_expr_t expr, struct vector_info res,
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,7 @@ 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(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(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_DAR_OBJ_REAL(vthread_t thr, vvp_code_t code);
|
||||||
|
extern bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_SET_VEC(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(vthread_t thr, vvp_code_t code);
|
||||||
extern bool of_SET_X0_X(vthread_t thr, vvp_code_t code);
|
extern bool of_SET_X0_X(vthread_t thr, vvp_code_t code);
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ static const struct opcode_table_s opcode_table[] = {
|
||||||
{ "%set/dar",of_SET_DAR,3, {OA_FUNC_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", 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/dar/obj/real",of_SET_DAR_OBJ_REAL,1,{OA_NUMBER,OA_NONE,OA_NONE} },
|
||||||
|
{ "%set/dar/obj/str", of_SET_DAR_OBJ_STR, 1,{OA_NUMBER,OA_NONE,OA_NONE} },
|
||||||
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
|
{ "%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} },
|
{ "%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} },
|
{ "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },
|
||||||
|
|
|
||||||
|
|
@ -963,10 +963,15 @@ 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>.
|
using a fixed index register, use the register addressed by <index>.
|
||||||
|
|
||||||
* %set/dar/obj/real <index>
|
* %set/dar/obj/real <index>
|
||||||
|
* %set/dar/obj/str <index>
|
||||||
|
|
||||||
The "%set/dar/obj/real" opcode sets the top value from the real-value
|
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 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.
|
stack. The intent is that this value may be written to a bunch of
|
||||||
|
values.
|
||||||
|
|
||||||
|
The "%set/dar/obj/str" opcode does the same but for string values and
|
||||||
|
uses the string stack.
|
||||||
|
|
||||||
* %set/v <var-label>, <bit>, <wid>
|
* %set/v <var-label>, <bit>, <wid>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4957,6 +4957,23 @@ bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* %set/dar/obj/str <index>
|
||||||
|
*/
|
||||||
|
bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t cp)
|
||||||
|
{
|
||||||
|
unsigned adr = thr->words[cp->number].w_int;
|
||||||
|
|
||||||
|
string value = thr->peek_str(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.
|
* This implements the "%set/v <label>, <bit>, <wid>" instruction.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue