tgt-vvp: Fix store skip for assignment operator on dynamic part select
The operator assignment on dynamic part selects uses the `%store/vec4` instruction to store the value. This instruction will skip the assignment if flag 4 is set. This is for handling the case where the index is undefined. Since the left hand side of the assignment is an arbitrary expression it can change the flag. The implementation handles this by making a copy of the flag and restoring it before executing the `%store/vec4` instruction. The flag is set by the `%ix/vec4` instruction when loading the index register. But the copy of the flag is made before that and just picks up the flag that was stored by previous expressions. This can cause the store to be skipped when it shouldn't. E.g. in the following code the increment will be skipped. Flag 4 is used from the `a == 0` comparison, rather than from computing the part select index. ``` int a = 0; if (a == 0) begin a[a+:2] += 1; end $display(a); // Will print 0, should print 1 ``` Fix this by moving the copy of the flag after the `%ix/vec4` instruction. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
2abfef68ff
commit
e263d5b268
|
|
@ -147,9 +147,9 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
|
|||
|
||||
fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word);
|
||||
draw_eval_vec4(part_off_ex);
|
||||
fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.part_select_dynamic.x_flag);
|
||||
fprintf(vvp_out, " %%dup/vec4;\n");
|
||||
fprintf(vvp_out, " %%ix/vec4 %d;\n", slice->u_.part_select_dynamic.word_idx_reg);
|
||||
fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.part_select_dynamic.x_flag);
|
||||
fprintf(vvp_out, " %%part/u %u;\n", wid);
|
||||
|
||||
} else if (ivl_signal_dimensions(sig) > 0 && word_ix == 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue