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, 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;

View File

@ -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
{ {

View File

@ -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)

View File

@ -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;

View File

@ -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;

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, " %%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;

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 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,

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(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);

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",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} },

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>. 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>

View File

@ -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.
* *