Add initial support for using a queue element as an L-value
This commit is contained in:
parent
520d5b392a
commit
c969c324ed
|
|
@ -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));
|
||||
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;
|
||||
break;
|
||||
}
|
||||
// FIXME
|
||||
#if 0
|
||||
static int show_stmt_assign_sig_darray(ivl_statement_t net)
|
||||
{
|
||||
|
||||
fprintf(vvp_out, " %%store/obj v%p_0;\n", var);
|
||||
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
darray->set_word(adr, value);
|
||||
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);
|
||||
|
||||
darray->set_word(adr, value);
|
||||
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);
|
||||
|
||||
darray->set_word(adr, value);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue