tgt-vvp: Don't accidentally skip assignment pattern initialization
The `%store/dar/...` and `%store/qdar/...` instructions are used to load a
value into an entry in dynamic array or queue. These instructions will skip
the load if VVP flag 4 is 1.
For assignment pattern initialization these instructions are used to load
the value of the individual assignment pattern expressions into the dynamic
array.
For queues flag 4 is never cleared when generating the code for the
assignment pattern. This means the initialization might be skipped
depending on what value the flag had before.
```
int a = 1;
int q[$];
a = a == 1;
q = {1, 2, 3, 4};
```
For dynamic arrays it is cleared once in the beginning. But each item in
the assignment pattern can be an arbitrary expression. Evaluating the
expression can cause the flag to get overwritten. E.g. the following code
will skip the assignments.
```
int a = 1;
int d[];
d = {a ? 1 : 1, 2, 3, 4};
```
To fix these issues make sure that the flag is cleared after evaluating
each initialization expression and before executing the `%store/...`
instruction.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
72b0498af4
commit
b11da7e16f
|
|
@ -968,18 +968,21 @@ static int show_stmt_assign_darray_pattern(ivl_statement_t net)
|
||||||
case IVL_VT_LOGIC:
|
case IVL_VT_LOGIC:
|
||||||
draw_eval_vec4(ivl_expr_parm(rval,idx));
|
draw_eval_vec4(ivl_expr_parm(rval,idx));
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
fprintf(vvp_out, " %%store/dar/vec4 v%p_0;\n", var);
|
fprintf(vvp_out, " %%store/dar/vec4 v%p_0;\n", var);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IVL_VT_REAL:
|
case IVL_VT_REAL:
|
||||||
draw_eval_real(ivl_expr_parm(rval,idx));
|
draw_eval_real(ivl_expr_parm(rval,idx));
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
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:
|
case IVL_VT_STRING:
|
||||||
draw_eval_string(ivl_expr_parm(rval,idx));
|
draw_eval_string(ivl_expr_parm(rval,idx));
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var);
|
fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1102,6 +1105,7 @@ static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval,
|
||||||
case IVL_VT_LOGIC:
|
case IVL_VT_LOGIC:
|
||||||
draw_eval_vec4(ivl_expr_parm(rval,idx));
|
draw_eval_vec4(ivl_expr_parm(rval,idx));
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, max_idx,
|
fprintf(vvp_out, " %%store/qdar/v v%p_0, %d, %u;\n", var, max_idx,
|
||||||
width_of_packed_type(element_type));
|
width_of_packed_type(element_type));
|
||||||
break;
|
break;
|
||||||
|
|
@ -1109,12 +1113,14 @@ static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval,
|
||||||
case IVL_VT_REAL:
|
case IVL_VT_REAL:
|
||||||
draw_eval_real(ivl_expr_parm(rval,idx));
|
draw_eval_real(ivl_expr_parm(rval,idx));
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, max_idx);
|
fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, max_idx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IVL_VT_STRING:
|
case IVL_VT_STRING:
|
||||||
draw_eval_string(ivl_expr_parm(rval,idx));
|
draw_eval_string(ivl_expr_parm(rval,idx));
|
||||||
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
|
||||||
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, max_idx);
|
fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, max_idx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue