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:
Stephen Williams 2013-10-19 15:11:13 -07:00
parent d5a0f2fc07
commit e60804cf41
11 changed files with 82 additions and 1 deletions

View File

@ -632,6 +632,9 @@ class PEString : public PExpr {
virtual unsigned test_width(Design*des, NetScope*scope,
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*,
unsigned expr_wid, unsigned) const;
verinum* eval_const(Design*, NetScope*) const;

View File

@ -4898,6 +4898,16 @@ unsigned PEString::test_width(Design*, NetScope*, width_mode_t&)
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*,
unsigned expr_wid, unsigned) const
{

View File

@ -214,7 +214,23 @@ void draw_ufunc_real(ivl_expr_t expr)
fprintf(vvp_out, " %%load/real v%p_0;\n", retval);
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)

View File

@ -90,6 +90,14 @@ static int eval_darray_new(ivl_expr_t ex)
fprintf(vvp_out, " %%pop/real 1;\n");
}
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:
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
errors += 1;
@ -123,6 +131,14 @@ static int eval_darray_new(ivl_expr_t ex)
}
fprintf(vvp_out, " %%pop/real 1;\n");
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:
fprintf(vvp_out, "; ERROR: Sorry, this type not supported here.\n");
errors += 1;

View File

@ -180,6 +180,10 @@ void draw_eval_string(ivl_expr_t expr)
fallback_eval(expr);
break;
case IVL_EX_UFUNC:
draw_ufunc_string(expr);
break;
default:
fallback_eval(expr);
break;

View File

@ -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, " %%store/dar/r v%p_0;\n", var);
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:
fprintf(vvp_out, "; ERROR: show_stmt_assign_darray_pattern: type_base=%d not implemented\n", ivl_type_base(element_type));
errors += 1;

View File

@ -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 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 pad_expr_in_place(ivl_expr_t expr, struct vector_info res,

View File

@ -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_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_STR(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);

View File

@ -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/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/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/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} },

View File

@ -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>.
* %set/dar/obj/real <index>
* %set/dar/obj/str <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.
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>

View File

@ -4957,6 +4957,23 @@ bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t cp)
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.
*