vec4 versions of compressed assignment statements.
This commit is contained in:
parent
c7e61f3aa4
commit
f5564a195f
|
|
@ -82,7 +82,7 @@ struct vec_slice_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice,
|
static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice,
|
||||||
unsigned bit, unsigned wid)
|
unsigned wid)
|
||||||
{
|
{
|
||||||
ivl_signal_t sig = ivl_lval_sig(lval);
|
ivl_signal_t sig = ivl_lval_sig(lval);
|
||||||
ivl_expr_t part_off_ex = ivl_lval_part_off(lval);
|
ivl_expr_t part_off_ex = ivl_lval_part_off(lval);
|
||||||
|
|
@ -116,8 +116,7 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
|
||||||
|
|
||||||
slice->type = SLICE_SIMPLE_VECTOR;
|
slice->type = SLICE_SIMPLE_VECTOR;
|
||||||
slice->u_.simple_vector.use_word = use_word;
|
slice->u_.simple_vector.use_word = use_word;
|
||||||
fprintf(vvp_out, " %%load/v %u, v%p_%lu, %u;\n",
|
fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word);
|
||||||
bit, sig, use_word, wid);
|
|
||||||
|
|
||||||
} else if (ivl_signal_dimensions(sig)==0 && part_off_ex==0 && word_ix==0) {
|
} else if (ivl_signal_dimensions(sig)==0 && part_off_ex==0 && word_ix==0) {
|
||||||
|
|
||||||
|
|
@ -126,35 +125,26 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
|
||||||
slice->type = SLICE_PART_SELECT_STATIC;
|
slice->type = SLICE_PART_SELECT_STATIC;
|
||||||
slice->u_.part_select_static.part_off = part_off;
|
slice->u_.part_select_static.part_off = part_off;
|
||||||
|
|
||||||
fprintf(vvp_out, " %%ix/load 1, %lu, 0;\n", part_off);
|
fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word);
|
||||||
fprintf(vvp_out, " %%load/x1p %u, v%p_0, %u;\n", bit, sig, wid);
|
fprintf(vvp_out, " %%pushi/vec4 %lu, 0, 32;\n", part_off);
|
||||||
|
fprintf(vvp_out, " %%part/u %u;\n", wid);
|
||||||
|
|
||||||
} else if (ivl_signal_dimensions(sig)==0 && part_off_ex!=0 && word_ix==0) {
|
} else if (ivl_signal_dimensions(sig)==0 && part_off_ex!=0 && word_ix==0) {
|
||||||
|
|
||||||
unsigned skip_set = transient_id++;
|
|
||||||
unsigned out_set = transient_id++;
|
|
||||||
|
|
||||||
assert(use_word == 0);
|
assert(use_word == 0);
|
||||||
assert(part_off == 0);
|
assert(part_off == 0);
|
||||||
|
|
||||||
slice->type = SLICE_PART_SELECT_DYNAMIC;
|
slice->type = SLICE_PART_SELECT_DYNAMIC;
|
||||||
|
|
||||||
draw_eval_expr_into_integer(part_off_ex, 1);
|
|
||||||
|
|
||||||
slice->u_.part_select_dynamic.word_idx_reg = allocate_word();
|
slice->u_.part_select_dynamic.word_idx_reg = allocate_word();
|
||||||
slice->u_.part_select_dynamic.x_flag = allocate_vector(1);
|
slice->u_.part_select_dynamic.x_flag = allocate_flag();
|
||||||
|
|
||||||
fprintf(vvp_out, " %%mov %u, %u, 1;\n",
|
fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word);
|
||||||
slice->u_.part_select_dynamic.x_flag, 4);
|
draw_eval_vec4(part_off_ex, STUFF_OK_XZ);
|
||||||
fprintf(vvp_out, " %%mov/wu %d, %d;\n",
|
fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.part_select_dynamic.x_flag);
|
||||||
slice->u_.part_select_dynamic.word_idx_reg, 1);
|
fprintf(vvp_out, " %%dup/vec4;\n");
|
||||||
|
fprintf(vvp_out, " %%ix/vec4 %u;\n", slice->u_.part_select_dynamic.word_idx_reg);
|
||||||
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set);
|
fprintf(vvp_out, " %%part/u %u;\n", wid);
|
||||||
fprintf(vvp_out, " %%load/x1p %u, v%p_0, %u;\n", bit, sig, wid);
|
|
||||||
fprintf(vvp_out, " %%jmp t_%u;\n", out_set);
|
|
||||||
fprintf(vvp_out, "t_%u ;\n", skip_set);
|
|
||||||
fprintf(vvp_out, " %%mov %u, 2, %u;\n", bit, wid);
|
|
||||||
fprintf(vvp_out, "t_%u ;\n", out_set);
|
|
||||||
|
|
||||||
} else if (ivl_signal_dimensions(sig) > 0 && word_ix == 0) {
|
} else if (ivl_signal_dimensions(sig) > 0 && word_ix == 0) {
|
||||||
|
|
||||||
|
|
@ -163,161 +153,152 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
|
||||||
if (use_word < ivl_signal_array_count(sig)) {
|
if (use_word < ivl_signal_array_count(sig)) {
|
||||||
fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n",
|
fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n",
|
||||||
use_word);
|
use_word);
|
||||||
fprintf(vvp_out, " %%load/av %u, v%p, %u;\n",
|
fprintf(vvp_out, " %%load/vec4a v%p, 3;\n", sig);
|
||||||
bit, sig, wid);
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(vvp_out, " %%mov %u, 2, %u; OUT OF BOUNDS\n",
|
assert(wid <= 32);
|
||||||
bit, wid);
|
fprintf(vvp_out, " %%pushi/vec4 4294967295, 4294967295, %u;\n", wid);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ivl_signal_dimensions(sig) > 0 && word_ix != 0) {
|
} else if (ivl_signal_dimensions(sig) > 0 && word_ix != 0) {
|
||||||
|
|
||||||
unsigned skip_set = transient_id++;
|
|
||||||
unsigned out_set = transient_id++;
|
|
||||||
slice->type = SLICE_MEMORY_WORD_DYNAMIC;
|
slice->type = SLICE_MEMORY_WORD_DYNAMIC;
|
||||||
|
|
||||||
draw_eval_expr_into_integer(word_ix, 3);
|
|
||||||
slice->u_.memory_word_dynamic.word_idx_reg = allocate_word();
|
slice->u_.memory_word_dynamic.word_idx_reg = allocate_word();
|
||||||
slice->u_.memory_word_dynamic.x_flag = allocate_vector(1);
|
slice->u_.memory_word_dynamic.x_flag = allocate_flag();
|
||||||
fprintf(vvp_out, " %%mov/wu %d, 3;\n",
|
|
||||||
slice->u_.memory_word_dynamic.word_idx_reg);
|
|
||||||
fprintf(vvp_out, " %%mov %u, 4, 1;\n",
|
|
||||||
slice->u_.memory_word_dynamic.x_flag);
|
|
||||||
|
|
||||||
fprintf(vvp_out, " %%jmp/1 t_%u, 4;\n", skip_set);
|
draw_eval_expr_into_integer(word_ix, slice->u_.memory_word_dynamic.word_idx_reg);
|
||||||
fprintf(vvp_out, " %%ix/load 1, 0, 0;\n");
|
fprintf(vvp_out, " %%flag_mov %d, 4;\n", slice->u_.memory_word_dynamic.x_flag);
|
||||||
fprintf(vvp_out, " %%load/av %u, v%p, %u;\n",
|
fprintf(vvp_out, " %%load/vec4a v%p, %d;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg);
|
||||||
bit, sig, wid);
|
|
||||||
fprintf(vvp_out, " %%jmp t_%u;\n", out_set);
|
|
||||||
fprintf(vvp_out, "t_%u ;\n", skip_set);
|
|
||||||
fprintf(vvp_out, " %%mov %u, 2, %u;\n", bit, wid);
|
|
||||||
fprintf(vvp_out, "t_%u ;\n", out_set);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vector_info get_vec_from_lval(ivl_statement_t net,
|
/*
|
||||||
struct vec_slice_info*slices)
|
* This loads the l-value values into the top of the stack, and also
|
||||||
|
* leaves in the slices the information needed to store the slice
|
||||||
|
* results back.
|
||||||
|
*/
|
||||||
|
static void get_vec_from_lval(ivl_statement_t net, struct vec_slice_info*slices)
|
||||||
{
|
{
|
||||||
struct vector_info res;
|
|
||||||
unsigned lidx;
|
unsigned lidx;
|
||||||
unsigned cur_bit;
|
unsigned cur_bit;
|
||||||
|
|
||||||
res.wid = ivl_stmt_lwidth(net);
|
unsigned wid = ivl_stmt_lwidth(net);
|
||||||
res.base = allocate_vector(res.wid);
|
|
||||||
|
|
||||||
cur_bit = 0;
|
cur_bit = 0;
|
||||||
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
|
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
|
||||||
unsigned bidx;
|
|
||||||
ivl_lval_t lval;
|
ivl_lval_t lval;
|
||||||
unsigned bit_limit = res.wid - cur_bit;
|
unsigned bit_limit = wid - cur_bit;
|
||||||
|
|
||||||
lval = ivl_stmt_lval(net, lidx);
|
lval = ivl_stmt_lval(net, lidx);
|
||||||
|
|
||||||
if (bit_limit > ivl_lval_width(lval))
|
if (bit_limit > ivl_lval_width(lval))
|
||||||
bit_limit = ivl_lval_width(lval);
|
bit_limit = ivl_lval_width(lval);
|
||||||
|
|
||||||
bidx = res.base + cur_bit;
|
get_vec_from_lval_slice(lval, slices+lidx, bit_limit);
|
||||||
|
if (lidx > 0) {
|
||||||
get_vec_from_lval_slice(lval, slices+lidx, bidx, bit_limit);
|
fprintf(vvp_out, " %%concat/vec4;\n");
|
||||||
|
}
|
||||||
|
|
||||||
cur_bit += bit_limit;
|
cur_bit += bit_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void put_vec_to_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice,
|
static void put_vec_to_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice,
|
||||||
unsigned bit, unsigned wid)
|
unsigned wid)
|
||||||
{
|
{
|
||||||
unsigned skip_set = transient_id++;
|
//unsigned skip_set = transient_id++;
|
||||||
struct vector_info tmp;
|
|
||||||
ivl_signal_t sig = ivl_lval_sig(lval);
|
ivl_signal_t sig = ivl_lval_sig(lval);
|
||||||
|
int part_off_idx;
|
||||||
|
|
||||||
/* If the slice of the l-value is a BOOL variable, then cast
|
/* If the slice of the l-value is a BOOL variable, then cast
|
||||||
the data to a BOOL vector so that the stores can be valid. */
|
the data to a BOOL vector so that the stores can be valid. */
|
||||||
if (ivl_signal_data_type(sig) == IVL_VT_BOOL) {
|
if (ivl_signal_data_type(sig) == IVL_VT_BOOL) {
|
||||||
fprintf(vvp_out, " %%cast2 %u, %u, %u;\n", bit, bit, wid);
|
fprintf(vvp_out, " %%cast2;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (slice->type) {
|
switch (slice->type) {
|
||||||
default:
|
default:
|
||||||
|
fprintf(vvp_out, " ; XXXX slice->type=%d\n", slice->type);
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SLICE_SIMPLE_VECTOR:
|
case SLICE_SIMPLE_VECTOR:
|
||||||
fprintf(vvp_out, " %%set/v v%p_%lu, %u, %u;\n",
|
fprintf(vvp_out, " %%store/vec4 v%p_%lu, 0, %u;\n",
|
||||||
sig, slice->u_.simple_vector.use_word, bit, wid);
|
sig, slice->u_.simple_vector.use_word, wid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SLICE_PART_SELECT_STATIC:
|
case SLICE_PART_SELECT_STATIC:
|
||||||
fprintf(vvp_out, " %%ix/load 0, %lu, 0;\n",
|
part_off_idx = allocate_word();
|
||||||
slice->u_.part_select_static.part_off);
|
fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n",
|
||||||
fprintf(vvp_out, " %%set/x0 v%p_0, %u, %u;\n", sig, bit, wid);
|
part_off_idx, slice->u_.part_select_static.part_off);
|
||||||
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
|
fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n",
|
||||||
|
sig, part_off_idx, wid);
|
||||||
|
clr_word(part_off_idx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SLICE_PART_SELECT_DYNAMIC:
|
case SLICE_PART_SELECT_DYNAMIC:
|
||||||
fprintf(vvp_out, " %%jmp/1 t_%u, %u;\n", skip_set,
|
fprintf(vvp_out, " %%flag_mov 4, %u;\n",
|
||||||
slice->u_.part_select_dynamic.x_flag);
|
slice->u_.part_select_dynamic.x_flag);
|
||||||
fprintf(vvp_out, " %%mov/wu 0, %d;\n",
|
fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n",
|
||||||
slice->u_.part_select_dynamic.word_idx_reg);
|
sig, slice->u_.part_select_dynamic.word_idx_reg, wid);
|
||||||
fprintf(vvp_out, " %%set/x0 v%p_0, %u, %u;\n", sig, bit, wid);
|
clr_word(slice->u_.part_select_dynamic.word_idx_reg);
|
||||||
fprintf(vvp_out, "t_%u ;\n", skip_set);
|
clr_flag(slice->u_.part_select_dynamic.x_flag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SLICE_MEMORY_WORD_STATIC:
|
case SLICE_MEMORY_WORD_STATIC:
|
||||||
if (slice->u_.simple_vector.use_word >= ivl_signal_array_count(sig))
|
if (slice->u_.memory_word_static.use_word < ivl_signal_array_count(sig)) {
|
||||||
break;
|
int word_idx = allocate_word();
|
||||||
fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n",
|
fprintf(vvp_out," %%flag_set/imm 4, 0;\n");
|
||||||
slice->u_.simple_vector.use_word);
|
fprintf(vvp_out," %%ix/load %d, %lu, 0;\n", word_idx, slice->u_.memory_word_static.use_word);
|
||||||
fprintf(vvp_out, " %%set/av v%p, %u, %u;\n",
|
fprintf(vvp_out," %%store/vec4a v%p, %d, 0;\n", sig, word_idx);
|
||||||
sig, bit, wid);
|
clr_word(word_idx);
|
||||||
|
} else {
|
||||||
|
fprintf(vvp_out," ; Skip this slice write to v%p [%lu]\n", sig, slice->u_.memory_word_static.use_word);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SLICE_MEMORY_WORD_DYNAMIC:
|
case SLICE_MEMORY_WORD_DYNAMIC:
|
||||||
fprintf(vvp_out, " %%jmp/1 t_%u, %u;\n", skip_set,
|
fprintf(vvp_out, " %%flag_mov 4, %d;\n", slice->u_.memory_word_dynamic.x_flag);
|
||||||
slice->u_.memory_word_dynamic.x_flag);
|
fprintf(vvp_out, " %%store/vec4a v%p, %d, 0;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg);
|
||||||
fprintf(vvp_out, " %%mov/wu 3, %d;\n",
|
|
||||||
slice->u_.memory_word_dynamic.word_idx_reg);
|
|
||||||
fprintf(vvp_out, " %%set/av v%p, %u, %u;\n",
|
|
||||||
ivl_lval_sig(lval), bit, wid);
|
|
||||||
fprintf(vvp_out, "t_%u ;\n", skip_set);
|
|
||||||
|
|
||||||
tmp.base = slice->u_.memory_word_dynamic.x_flag;
|
|
||||||
tmp.wid = 1;
|
|
||||||
clr_vector(tmp);
|
|
||||||
clr_word(slice->u_.memory_word_dynamic.word_idx_reg);
|
clr_word(slice->u_.memory_word_dynamic.word_idx_reg);
|
||||||
|
clr_flag(slice->u_.memory_word_dynamic.x_flag);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void put_vec_to_lval(ivl_statement_t net, struct vec_slice_info*slices,
|
static void put_vec_to_lval(ivl_statement_t net, struct vec_slice_info*slices)
|
||||||
struct vector_info res)
|
|
||||||
{
|
{
|
||||||
unsigned lidx;
|
unsigned lidx;
|
||||||
unsigned cur_bit;
|
unsigned cur_bit;
|
||||||
|
|
||||||
|
unsigned wid = ivl_stmt_lwidth(net);
|
||||||
|
|
||||||
cur_bit = 0;
|
cur_bit = 0;
|
||||||
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
|
for (lidx = 0 ; lidx < ivl_stmt_lvals(net) ; lidx += 1) {
|
||||||
unsigned bidx;
|
|
||||||
ivl_lval_t lval;
|
ivl_lval_t lval;
|
||||||
unsigned bit_limit = res.wid - cur_bit;
|
unsigned bit_limit = wid - cur_bit;
|
||||||
|
|
||||||
lval = ivl_stmt_lval(net, lidx);
|
lval = ivl_stmt_lval(net, lidx);
|
||||||
|
|
||||||
if (bit_limit > ivl_lval_width(lval))
|
if (bit_limit > ivl_lval_width(lval))
|
||||||
bit_limit = ivl_lval_width(lval);
|
bit_limit = ivl_lval_width(lval);
|
||||||
|
|
||||||
bidx = res.base + cur_bit;
|
if (lidx+1 < ivl_stmt_lvals(net))
|
||||||
|
fprintf(vvp_out, " %%split/vec4 %u;\n", bit_limit);
|
||||||
|
|
||||||
put_vec_to_lval_slice(lval, slices+lidx, bidx, bit_limit);
|
put_vec_to_lval_slice(lval, slices+lidx, bit_limit);
|
||||||
|
|
||||||
cur_bit += bit_limit;
|
cur_bit += bit_limit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static ivl_type_t draw_lval_expr(ivl_lval_t lval)
|
static ivl_type_t draw_lval_expr(ivl_lval_t lval)
|
||||||
{
|
{
|
||||||
ivl_lval_t lval_nest = ivl_lval_nest(lval);
|
ivl_lval_t lval_nest = ivl_lval_nest(lval);
|
||||||
|
|
@ -338,6 +319,7 @@ static ivl_type_t draw_lval_expr(ivl_lval_t lval)
|
||||||
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
fprintf(vvp_out, " %%pop/obj 1, 1;\n");
|
||||||
return ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval));
|
return ivl_type_prop_type(sub_type, ivl_lval_property_idx(lval));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void set_vec_to_lval_slice_nest(ivl_lval_t lval, unsigned bit, unsigned wid)
|
static void set_vec_to_lval_slice_nest(ivl_lval_t lval, unsigned bit, unsigned wid)
|
||||||
|
|
@ -616,15 +598,16 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
||||||
{
|
{
|
||||||
ivl_expr_t rval = ivl_stmt_rval(net);
|
ivl_expr_t rval = ivl_stmt_rval(net);
|
||||||
//struct vector_info res;
|
//struct vector_info res;
|
||||||
struct vector_info lres = {0, 0};
|
//struct vector_info lres = {0, 0};
|
||||||
struct vec_slice_info*slices = 0;
|
struct vec_slice_info*slices = 0;
|
||||||
|
int idx_reg;
|
||||||
|
|
||||||
/* If this is a compressed assignment, then get the contents
|
/* If this is a compressed assignment, then get the contents
|
||||||
of the l-value. We need these values as part of the r-value
|
of the l-value. We need these values as part of the r-value
|
||||||
calculation. */
|
calculation. */
|
||||||
if (ivl_stmt_opcode(net) != 0) {
|
if (ivl_stmt_opcode(net) != 0) {
|
||||||
slices = calloc(ivl_stmt_lvals(net), sizeof(struct vec_slice_info));
|
slices = calloc(ivl_stmt_lvals(net), sizeof(struct vec_slice_info));
|
||||||
lres = get_vec_from_lval(net, slices);
|
get_vec_from_lval(net, slices);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the special case that the expression is a real
|
/* Handle the special case that the expression is a real
|
||||||
|
|
@ -662,123 +645,71 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
||||||
case 0:
|
case 0:
|
||||||
store_vec4_to_lval(net);
|
store_vec4_to_lval(net);
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
// XXXX These need to be converted to vec4 style.
|
|
||||||
case '+':
|
case '+':
|
||||||
if (res.base > 3) {
|
fprintf(vvp_out, " %%add;\n");
|
||||||
fprintf(vvp_out, " %%add %u, %u, %u;\n",
|
put_vec_to_lval(net, slices);
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, " %%add %u, %u, %u;\n",
|
|
||||||
lres.base, res.base, res.wid);
|
|
||||||
res.base = lres.base;
|
|
||||||
}
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
fprintf(vvp_out, " %%sub %u, %u, %u;\n",
|
fprintf(vvp_out, " %%sub;\n");
|
||||||
lres.base, res.base, res.wid);
|
put_vec_to_lval(net, slices);
|
||||||
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
|
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
if (res.base > 3) {
|
fprintf(vvp_out, " %%mul;\n");
|
||||||
fprintf(vvp_out, " %%mul %u, %u, %u;\n",
|
put_vec_to_lval(net, slices);
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, " %%mul %u, %u, %u;\n",
|
|
||||||
lres.base, res.base, res.wid);
|
|
||||||
res.base = lres.base;
|
|
||||||
}
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '/':
|
case '/':
|
||||||
fprintf(vvp_out, " %%div%s %u, %u, %u;\n",
|
fprintf(vvp_out, " %%div%s;\n", ivl_expr_signed(rval)? "/s":"");
|
||||||
ivl_expr_signed(rval)? "/s" : "",
|
put_vec_to_lval(net, slices);
|
||||||
lres.base, res.base, res.wid);
|
|
||||||
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
|
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '%':
|
case '%':
|
||||||
fprintf(vvp_out, " %%mod%s %u, %u, %u;\n",
|
fprintf(vvp_out, " %%mod%s;\n", ivl_expr_signed(rval)? "/s":"");
|
||||||
ivl_expr_signed(rval)? "/s" : "",
|
put_vec_to_lval(net, slices);
|
||||||
lres.base, res.base, res.wid);
|
|
||||||
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
|
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '&':
|
case '&':
|
||||||
if (res.base > 3) {
|
fprintf(vvp_out, " %%and;\n");
|
||||||
fprintf(vvp_out, " %%and %u, %u, %u;\n",
|
put_vec_to_lval(net, slices);
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, " %%and %u, %u, %u;\n",
|
|
||||||
lres.base, res.base, res.wid);
|
|
||||||
res.base = lres.base;
|
|
||||||
}
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '|':
|
case '|':
|
||||||
if (res.base > 3) {
|
fprintf(vvp_out, " %%or;\n");
|
||||||
fprintf(vvp_out, " %%or %u, %u, %u;\n",
|
put_vec_to_lval(net, slices);
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, " %%or %u, %u, %u;\n",
|
|
||||||
lres.base, res.base, res.wid);
|
|
||||||
res.base = lres.base;
|
|
||||||
}
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '^':
|
case '^':
|
||||||
if (res.base > 3) {
|
fprintf(vvp_out, " %%xor;\n");
|
||||||
fprintf(vvp_out, " %%xor %u, %u, %u;\n",
|
put_vec_to_lval(net, slices);
|
||||||
res.base, lres.base, res.wid);
|
|
||||||
clr_vector(lres);
|
|
||||||
} else {
|
|
||||||
fprintf(vvp_out, " %%xor %u, %u, %u;\n",
|
|
||||||
lres.base, res.base, res.wid);
|
|
||||||
res.base = lres.base;
|
|
||||||
}
|
|
||||||
put_vec_to_lval(net, slices, res);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l': /* lres <<= res */
|
case 'l': /* lval <<= expr */
|
||||||
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", res.base, res.wid);
|
idx_reg = allocate_word();
|
||||||
fprintf(vvp_out, " %%shiftl/i0 %u, %u;\n", lres.base, res.wid);
|
fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg);
|
||||||
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
|
fprintf(vvp_out, " %%shiftl %d;\n", idx_reg);
|
||||||
res.base, lres.base, res.wid);
|
clr_word(idx_reg);
|
||||||
|
put_vec_to_lval(net, slices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r': /* lres >>= res */
|
case 'r': /* lval >>= expr */
|
||||||
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", res.base, res.wid);
|
idx_reg = allocate_word();
|
||||||
fprintf(vvp_out, " %%shiftr/i0 %u, %u;\n", lres.base, res.wid);
|
fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg);
|
||||||
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
|
fprintf(vvp_out, " %%shiftr %d;\n", idx_reg);
|
||||||
res.base, lres.base, res.wid);
|
clr_word(idx_reg);
|
||||||
|
put_vec_to_lval(net, slices);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R': /* lres >>>= res */
|
case 'R': /* lval >>>= expr */
|
||||||
fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", res.base, res.wid);
|
idx_reg = allocate_word();
|
||||||
fprintf(vvp_out, " %%shiftr/s/i0 %u, %u;\n", lres.base, res.wid);
|
fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg);
|
||||||
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
|
fprintf(vvp_out, " %%shiftr/s %d;\n", idx_reg);
|
||||||
res.base, lres.base, res.wid);
|
clr_word(idx_reg);
|
||||||
|
put_vec_to_lval(net, slices);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net));
|
fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net));
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
|
||||||
|
|
@ -294,11 +294,10 @@ Perform a continuous assign of a constant real value to the target
|
||||||
variable. See %cassign/v above. The value is popped from the real
|
variable. See %cassign/v above. The value is popped from the real
|
||||||
value stack.
|
value stack.
|
||||||
|
|
||||||
* %cast2 <dst>, <src>, <wid>
|
* %cast2
|
||||||
|
|
||||||
Convert the source vector, of type logic, to a bool vector by
|
Pop a value from the vec4 stack, convert it using Verilog rules to a
|
||||||
changing all the X and Z bits to 0. The source and destinations may
|
vector2 (binary) value, and push the result.
|
||||||
overlap.
|
|
||||||
|
|
||||||
* %cmp/u <bit-l>, <bit-r>, <wid> (XXXX Old meaning)
|
* %cmp/u <bit-l>, <bit-r>, <wid> (XXXX Old meaning)
|
||||||
* %cmp/s <bit-l>, <bit-r>, <wid> (XXXX Old meaning)
|
* %cmp/s <bit-l>, <bit-r>, <wid> (XXXX Old meaning)
|
||||||
|
|
@ -1006,7 +1005,8 @@ stack. If this item is larger then this, it is truncated. If smaller,
|
||||||
then extended. The /s variant sign extends, the /u variant unsigned
|
then extended. The /s variant sign extends, the /u variant unsigned
|
||||||
extends.
|
extends.
|
||||||
|
|
||||||
* %part <wid>
|
* %part/s <wid>
|
||||||
|
* %part/u <wid>
|
||||||
|
|
||||||
This instruction implements a part select. It pops from the top of the
|
This instruction implements a part select. It pops from the top of the
|
||||||
vec4 the base value, then it pops the base to select from. The width
|
vec4 the base value, then it pops the base to select from. The width
|
||||||
|
|
@ -1117,7 +1117,8 @@ Release the force on the real signal that is represented by the functor
|
||||||
statement. The <type> is 0 for nets and 1 for registers. See the other
|
statement. The <type> is 0 for nets and 1 for registers. See the other
|
||||||
%release commands above.
|
%release commands above.
|
||||||
|
|
||||||
* %replicate <count>
|
* %repli
|
||||||
|
cate <count>
|
||||||
|
|
||||||
Pop the vec4 value, replicate it <count> times, then push the
|
Pop the vec4 value, replicate it <count> times, then push the
|
||||||
result. In other words, push the concatenation of <count> copies.
|
result. In other words, push the concatenation of <count> copies.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue