Add initial support for using a queue element as an L-value

This commit is contained in:
Cary R 2020-07-26 14:00:16 -07:00
parent 520d5b392a
commit c969c324ed
3 changed files with 155 additions and 30 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2019 Stephen Williams (steve@icarus.com)
* Copyright (c) 2011-2020 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -1050,22 +1050,68 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net)
int errors = 0;
ivl_lval_t lval = ivl_stmt_lval(net, 0);
ivl_expr_t rval = ivl_stmt_rval(net);
ivl_expr_t part = ivl_lval_part_off(lval);
ivl_signal_t var= ivl_lval_sig(lval);
ivl_type_t var_type= ivl_signal_net_type(var);
ivl_type_t element_type = ivl_type_element(var_type);
ivl_expr_t mux = ivl_lval_idx(lval);
assert(ivl_stmt_lvals(net) == 1);
assert(ivl_stmt_opcode(net) == 0);
assert(part == 0);
assert(ivl_type_base(var_type) == IVL_VT_QUEUE);
switch (ivl_expr_type(rval)) {
case IVL_EX_NULL:
if (ivl_expr_type(rval) == IVL_EX_NULL) {
errors += draw_eval_object(rval);
break;
default:
fprintf(stderr, "XXXX: I don't know how to handle expr_type=%d here\n", ivl_expr_type(rval));
fprintf(vvp_out, " ; XXXX expr_type=%d\n", ivl_expr_type(rval));
errors += 1;
break;
}
fprintf(vvp_out, " %%store/obj v%p_0;\n", var);
} else if (mux && (ivl_type_base(element_type)==IVL_VT_REAL)) {
draw_eval_real(rval);
/* The %store/dar expects the array index to be in
index register 3. */
draw_eval_expr_into_integer(mux, 3);
fprintf(vvp_out, " %%store/dar/r v%p_0;\n", var);
} else if (mux && ivl_type_base(element_type)==IVL_VT_STRING) {
draw_eval_string(rval);
/* The %store/dar expects the array index to be in
index register 3. */
draw_eval_expr_into_integer(mux, 3);
fprintf(vvp_out, " %%store/dar/str v%p_0;\n", var);
} else if (mux) { // What is left must be some form of vector
draw_eval_vec4(rval);
resize_vec4_wid(rval, ivl_stmt_lwidth(net));
/* The %store/dar expects the array index to be in
index register 3. */
draw_eval_expr_into_integer(mux, 3);
fprintf(vvp_out, " %%store/dar/vec4 v%p_0;\n", var);
} else {
fprintf(stderr, "Sorry: I don't know how to handle expr_type=%d "
"being assigned to a queue.\n", ivl_expr_type(rval));
fprintf(vvp_out, " ; Sorry: Queues do not currently handle "
"expr_type=%d.\n", ivl_expr_type(rval));
errors += 1;
}
// FIXME
#if 0
static int show_stmt_assign_sig_darray(ivl_statement_t net)
{
} else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) {
/* There is no l-value mux, but the r-value is an array
pattern. This is a special case of an assignment to
elements of the l-value. */
errors += show_stmt_assign_darray_pattern(net);
} else {
/* There is no l-value mux, so this must be an
assignment to the array as a whole. Evaluate the
"object", and store the evaluated result. */
errors += draw_eval_object(rval);
fprintf(vvp_out, " %%store/obj v%p_0;\n", var);
}
#endif
return errors;
}

View File

@ -5643,21 +5643,40 @@ bool of_SPLIT_VEC4(vthread_t thr, vvp_code_t cp)
return true;
}
/*
* %store/dar/real <var>
* In this case, <var> is the name of a dynamic array. Signed index
* register 3 contains the index into the dynamic array.
*/
bool of_STORE_DAR_R(vthread_t thr, vvp_code_t cp)
{
long adr = thr->words[3].w_int;
// Pop the real value to be store...
double value = thr->pop_real();
int64_t adr = thr->words[3].w_int;
double value = thr->pop_real(); // Pop the real value to store...
vvp_net_t*net = cp->net;
unsigned max_size = 0; // FIXME: Need to get this from the compile and how to pass to set_word()
assert(net);
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_darray*darray = obj->get_object().peek<vvp_darray>();
assert(darray);
if (adr < 0)
cerr << "Warning: cannot write to a negative array<real> index ("
<< adr << ")." << endl;
else if (thr->flags[4] != BIT4_0)
cerr << "Warning: cannot write to an undefined array<real> index."
<< endl;
else if (darray)
darray->set_word(adr, value);
else {
vvp_queue*queue = get_queue_object<vvp_queue_real>(thr, net);
if (queue)
queue->push_front(value, max_size);
else
cerr << "Warning: cannot write to an undefined array<real>."
<< endl;
}
return true;
}
@ -5668,38 +5687,71 @@ bool of_STORE_DAR_R(vthread_t thr, vvp_code_t cp)
*/
bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t cp)
{
long adr = thr->words[3].w_int;
// Pop the string to be stored...
string value = thr->pop_str();
int64_t adr = thr->words[3].w_int;
string value = thr->pop_str(); // Pop the string to be stored...
vvp_net_t*net = cp->net;
unsigned max_size = 0; // FIXME: Need to get this from the compile and how to pass to set_word()
assert(net);
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_darray*darray = obj->get_object().peek<vvp_darray>();
assert(darray);
if (adr < 0)
cerr << "Warning: cannot write to a negative array<string> index ("
<< adr << ")." << endl;
else if (thr->flags[4] != BIT4_0)
cerr << "Warning: cannot write to an undefined array<string> index."
<< endl;
else if (darray)
darray->set_word(adr, value);
else {
vvp_queue*queue = get_queue_object<vvp_queue_string>(thr, net);
if (queue)
queue->push_front(value, max_size);
else
cerr << "Warning: cannot write to an undefined array<string>."
<< endl;
}
return true;
}
/*
* %store/dar/vec4 <var>
* In this case, <var> is the name of a dynamic array. Signed index
* register 3 contains the index into the dynamic array.
*/
bool of_STORE_DAR_VEC4(vthread_t thr, vvp_code_t cp)
{
long adr = thr->words[3].w_int;
// Pop the real value to be store...
vvp_vector4_t value = thr->pop_vec4();
int64_t adr = thr->words[3].w_int;
vvp_vector4_t value = thr->pop_vec4(); // Pop the real value to be store...
vvp_net_t*net = cp->net;
unsigned max_size = 0; // FIXME: Need to get this from the compile and how to pass to set_word()
assert(net);
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_darray*darray = obj->get_object().peek<vvp_darray>();
assert(darray);
if (adr < 0)
cerr << "Warning: cannot write to a negative array<vector["
<< value.size() << "]> index (" << adr << ")." << endl;
else if (thr->flags[4] != BIT4_0)
cerr << "Warning: cannot write to an undefined array<vector["
<< value.size() << "]> index." << endl;
else if (darray)
darray->set_word(adr, value);
else {
vvp_queue*queue = get_queue_object<vvp_queue_vec4>(thr, net);
if (queue)
queue->push_front(value, max_size);
else
cerr << "Warning: cannot write to an undefined array<vector["
<< value.size() << "]>." << endl;
}
return true;
}

View File

@ -446,8 +446,17 @@ vvp_queue_real::~vvp_queue_real()
void vvp_queue_real::set_word(unsigned adr, double value)
{
unsigned max_size = 0; // FIXME: need to get this from the compiler; bounded queues will fail
if (adr < queue.size())
queue[adr] = value;
else if (adr == queue.size())
if (!max_size || (queue.size() < max_size)) queue.push_back(value);
else cerr << "Warning: assigning to queue<real>[" << adr << "] is"
" outside bound (" << max_size << "). " << value
<< " was not added." << endl;
else cerr << "Warning: assigning to queue<real>[" << adr << "] is outside "
"of size (" << queue.size() << "). " << value
<< " was not added." << endl;
}
void vvp_queue_real::get_word(unsigned adr, double&value)
@ -498,8 +507,17 @@ vvp_queue_string::~vvp_queue_string()
void vvp_queue_string::set_word(unsigned adr, const string&value)
{
unsigned max_size = 0; // FIXME: need to get this from the compiler; bounded queues will fail
if (adr < queue.size())
queue[adr] = value;
else if (adr == queue.size())
if (!max_size || (queue.size() < max_size)) queue.push_back(value);
else cerr << "Warning: assigning to queue<string>[" << adr << "] is"
" outside bound (" << max_size << "). " << value
<< " was not added." << endl;
else cerr << "Warning: assigning to queue<string>[" << adr << "] is outside "
"of size (" << queue.size() << "). " << value
<< " was not added." << endl;
}
void vvp_queue_string::get_word(unsigned adr, string&value)
@ -550,8 +568,17 @@ vvp_queue_vec4::~vvp_queue_vec4()
void vvp_queue_vec4::set_word(unsigned adr, const vvp_vector4_t&value)
{
unsigned max_size = 0; // FIXME: need to get this from the compiler; bounded queues will fail
if (adr < queue.size())
queue[adr] = value;
else if (adr == queue.size())
if (!max_size || (queue.size() < max_size)) queue.push_back(value);
else cerr << "Warning: assigning to queue<vector>[" << adr << "] is"
" outside bound (" << max_size << "). " << value
<< " was not added." << endl;
else cerr << "Warning: assigning to queue<vector>[" << adr << "] is outside "
"of size (" << queue.size() << "). " << value
<< " was not added." << endl;
}
void vvp_queue_vec4::get_word(unsigned adr, vvp_vector4_t&value)