vec4 versions of compressed assignment statements.

This commit is contained in:
Stephen Williams 2014-02-06 09:55:25 -08:00
parent c7e61f3aa4
commit f5564a195f
2 changed files with 118 additions and 186 deletions

View File

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

View File

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