Vec4 store to memories.
This also reworks the working of the %store/vec4 instruction to take a part offset, and eliminate the %store/vec4/off instruction.
This commit is contained in:
parent
63fa44fa4a
commit
1a3adbe9cd
|
|
@ -36,7 +36,7 @@ static void function_argument_logic(ivl_signal_t port, ivl_expr_t expr)
|
|||
if (ewidth < pwidth)
|
||||
fprintf(vvp_out, " %%pad/u %u;\n", pwidth);
|
||||
|
||||
fprintf(vvp_out, " %%store/vec4 v%p_0, %u;\n", port, pwidth);
|
||||
fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n", port, pwidth);
|
||||
}
|
||||
|
||||
static void function_argument_real(ivl_signal_t port, ivl_expr_t expr)
|
||||
|
|
|
|||
|
|
@ -565,22 +565,44 @@ static void store_vec4_to_lval(ivl_statement_t net)
|
|||
unsigned lwid = ivl_lval_width(lval);
|
||||
|
||||
ivl_expr_t part_off_ex = ivl_lval_part_off(lval);
|
||||
/* This is non-nil if the l-val is the word of a memory,
|
||||
and nil otherwise. */
|
||||
ivl_expr_t word_ex = ivl_lval_idx(lval);
|
||||
|
||||
if (lidx+1 < ivl_stmt_lvals(net))
|
||||
fprintf(vvp_out, " %%split/vec4 %u;\n", lwid);
|
||||
|
||||
if (word_ex) {
|
||||
/* Handle index into an array */
|
||||
int word_index = allocate_word();
|
||||
int part_index = 0;
|
||||
/* Calculate the word address into word_index */
|
||||
draw_eval_expr_into_integer(word_ex, word_index);
|
||||
/* If there is a part_offset, calcualte it into part_index. */
|
||||
if (part_off_ex) {
|
||||
part_index = allocate_word();
|
||||
draw_eval_expr_into_integer(part_off_ex, part_index);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%store/vec4a v%p, %d, %d;\n",
|
||||
lsig, word_index, part_index);
|
||||
|
||||
clr_word(word_index);
|
||||
if (part_index)
|
||||
clr_word(part_index);
|
||||
|
||||
} else if (part_off_ex) {
|
||||
/* Dynamically calculated part offset */
|
||||
int offset_index = allocate_word();
|
||||
draw_eval_expr_into_integer(part_off_ex, offset_index);
|
||||
fprintf(vvp_out, " %%store/vec4/off v%p_0, %d, %u;\n",
|
||||
fprintf(vvp_out, " %%store/vec4 v%p_0, %d, %u;\n",
|
||||
lsig, offset_index, lwid);
|
||||
clr_word(offset_index);
|
||||
|
||||
} else {
|
||||
/* No offset expression, so use simpler store function. */
|
||||
assert(lwid == ivl_signal_width(lsig));
|
||||
fprintf(vvp_out, " %%store/vec4 v%p_0, %u;\n", lsig, lwid);
|
||||
fprintf(vvp_out, " %%store/vec4 v%p_0, 0, %u;\n", lsig, lwid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -588,7 +610,7 @@ static void store_vec4_to_lval(ivl_statement_t net)
|
|||
static int show_stmt_assign_vector(ivl_statement_t net)
|
||||
{
|
||||
ivl_expr_t rval = ivl_stmt_rval(net);
|
||||
struct vector_info res;
|
||||
//struct vector_info res;
|
||||
struct vector_info lres = {0, 0};
|
||||
struct vec_slice_info*slices = 0;
|
||||
|
||||
|
|
@ -610,30 +632,25 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
|||
assignment. */
|
||||
unsigned wid = ivl_stmt_lwidth(net);
|
||||
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
|
||||
if (res.base == 0) {
|
||||
fprintf(stderr, "%s:%u: vvp.tgt error: "
|
||||
"Unable to allocate %u thread bits for "
|
||||
"r-value expression.\n", ivl_expr_file(rval),
|
||||
ivl_expr_lineno(rval), wid);
|
||||
vvp_errors += 1;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%cvt/vr %u, %u;\n", res.base, res.wid);
|
||||
/* Convert a calculated real value to a vec4 value of
|
||||
the given width. We need to include the width of the
|
||||
result because real values to not have any inherit
|
||||
width. The real value will be popped, and a vec4
|
||||
value pushed. */
|
||||
fprintf(vvp_out, " %%cvt/vr %u;\n", wid);
|
||||
|
||||
} else {
|
||||
draw_eval_vec4(rval, 0);
|
||||
res.base = 0; // XXXX This is just to suppress the clr_vector below.
|
||||
res.wid = 0;
|
||||
//res.base = 0; // XXXX This is just to suppress the clr_vector below.
|
||||
//res.wid = 0;
|
||||
}
|
||||
|
||||
switch (ivl_stmt_opcode(net)) {
|
||||
case 0:
|
||||
store_vec4_to_lval(net);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
// XXXX These need to be converted to vec4 style.
|
||||
case '+':
|
||||
if (res.base > 3) {
|
||||
fprintf(vvp_out, " %%add %u, %u, %u;\n",
|
||||
|
|
@ -748,7 +765,7 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
|||
fprintf(vvp_out, " %%mov %u, %u, %u;\n",
|
||||
res.base, lres.base, res.wid);
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net));
|
||||
assert(0);
|
||||
|
|
@ -757,8 +774,6 @@ static int show_stmt_assign_vector(ivl_statement_t net)
|
|||
|
||||
if (slices)
|
||||
free(slices);
|
||||
if (res.base > 3)
|
||||
clr_vector(res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ extern bool of_STORE_REALA(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_STORE_STR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_STRA(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_VEC4(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_VEC4_OFF(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_STORE_VEC4A(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SUB(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SUB_WR(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_SUBI(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -267,8 +267,8 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%store/reala", of_STORE_REALA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%store/str", of_STORE_STR, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%store/stra", of_STORE_STRA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%store/vec4", of_STORE_VEC4, 2, {OA_FUNC_PTR,OA_BIT1, OA_NONE} },
|
||||
{ "%store/vec4/off",of_STORE_VEC4_OFF,3, {OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%store/vec4", of_STORE_VEC4, 3, {OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
|
||||
{ "%store/vec4a", of_STORE_VEC4A, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} },
|
||||
{ "%sub", of_SUB, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%sub/wr", of_SUB_WR, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%subi", of_SUBI, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
|
|
|
|||
|
|
@ -1128,7 +1128,7 @@ register that contains the LSB of the vector, and the <wid> is the
|
|||
size of the vector. The width must exactly match the width of the
|
||||
signal.
|
||||
|
||||
* %set/av <array-label>, <bit>, <wid>
|
||||
* %set/av <array-label>, <bit>, <wid> (XXXX Old definition)
|
||||
|
||||
This sets a thread vector to an array word. The <array-label>
|
||||
addresses an array device, and the <bit>,<wid> describe a vector to be
|
||||
|
|
@ -1239,16 +1239,23 @@ The %store/stra targets an array.
|
|||
The %store/dar/str is similar, but the target is a dynamic array of
|
||||
string string. The index is taken from signed index register 3.
|
||||
|
||||
* %store/vec4 <var-label>, <wid>
|
||||
* %store/vec4/off <var-label>, <offset>, <wid>
|
||||
* %store/vec4 <var-label>, <offset>, <wid>
|
||||
* %store/vec4a <var-label>, <addr>, <offset>
|
||||
|
||||
Store a logic vector into the variable. The value (and its width) is
|
||||
popped off the top of the stack and written to the variable. The value
|
||||
is then optionally truncated to <wid> bits and assigned to the
|
||||
variable. It is an error for the value to be fewer then <wid> bits.
|
||||
variable. It is an error for the value to be fewer then <wid>
|
||||
bits. The <offset> is the index register that contains a part offset
|
||||
for writing into a part of the variable.
|
||||
|
||||
The %store/vec4/off is similar, but it uses the index register
|
||||
<offset> to get a vector offset into the target vec4 variable.
|
||||
The %store/vec4a is similar, but the target is an array of vec4, the
|
||||
<addr> is an index register that contains the canonical address, and
|
||||
the <offset> is an index register that contains the vector part
|
||||
offset.
|
||||
|
||||
Both index registers can be 0, to mean a zero value instead of a zero
|
||||
register.
|
||||
|
||||
NOTE: The <wid> is not necessary, and should be removed.
|
||||
|
||||
|
|
|
|||
|
|
@ -6035,47 +6035,55 @@ bool of_STORE_STRA(vthread_t thr, vvp_code_t cp)
|
|||
}
|
||||
|
||||
/*
|
||||
* %store/vec4 <var-label>, <wid>
|
||||
* %store/vec4 <var-label>, <offset>, <wid>
|
||||
*/
|
||||
bool of_STORE_VEC4(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
/* Set the value into port 0 of the destination */
|
||||
vvp_net_ptr_t ptr (cp->net, 0);
|
||||
unsigned wid = cp->bit_idx[0];
|
||||
|
||||
vvp_vector4_t val = thr->pop_vec4();
|
||||
assert(val.size() >= wid);
|
||||
if (val.size() > wid)
|
||||
val.resize(wid);
|
||||
|
||||
vvp_send_vec4(ptr, val, thr->wt_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %storevec4/off <var-label>, <offset>, <wid>
|
||||
*/
|
||||
bool of_STORE_VEC4_OFF(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vvp_net_ptr_t ptr(cp->net, 0);
|
||||
vvp_signal_value*sig = dynamic_cast<vvp_signal_value*> (cp->net->fil);
|
||||
unsigned off_index = cp->bit_idx[0];
|
||||
unsigned wid = cp->bit_idx[1];
|
||||
|
||||
int off = thr->words[off_index].w_int;
|
||||
int off = off_index? thr->words[off_index].w_int : 0;
|
||||
|
||||
vvp_vector4_t val = thr->pop_vec4();
|
||||
assert(val.size() >= wid);
|
||||
if (val.size() > wid)
|
||||
val.resize(wid);
|
||||
|
||||
if (off==0 && val.size()==sig->value_size())
|
||||
vvp_send_vec4(ptr, val, thr->wt_context);
|
||||
else
|
||||
vvp_send_vec4_pv(ptr, val, off, wid, sig->value_size(), thr->wt_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_SUB(vthread_t thr, vvp_code_t cp)
|
||||
/*
|
||||
* %store/vec4a <var-label>, <addr>, <offset>
|
||||
*/
|
||||
bool of_STORE_VEC4A(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned adr_index = cp->bit_idx[0];
|
||||
unsigned off_index = cp->bit_idx[1];
|
||||
|
||||
vvp_vector4_t value = thr->pop_vec4();
|
||||
|
||||
long adr = adr_index? thr->words[adr_index].w_int : 0;
|
||||
long off = off_index? thr->words[off_index].w_int : 0;
|
||||
|
||||
array_set_word(cp->array, adr, off, value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %sub
|
||||
* pop r;
|
||||
* pop l;
|
||||
* push l-r;
|
||||
*/
|
||||
bool of_SUB(vthread_t thr, vvp_code_t)
|
||||
{
|
||||
vvp_vector4_t r = thr->pop_vec4();
|
||||
vvp_vector4_t l = thr->pop_vec4();
|
||||
|
|
@ -6110,7 +6118,7 @@ bool of_SUB(vthread_t thr, vvp_code_t cp)
|
|||
delete[]lva;
|
||||
delete[]lvb;
|
||||
|
||||
vvp_vector4_t tmp(cp->number, BIT4_X);
|
||||
vvp_vector4_t tmp(wid, BIT4_X);
|
||||
thr->push_vec4(tmp);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue