Switch qinsert to use a template
This commit is contained in:
parent
d1d6c0f5d2
commit
84eb70660d
199
vvp/vthread.cc
199
vvp/vthread.cc
|
|
@ -420,6 +420,60 @@ template <class VVP_QUEUE> static vvp_queue*get_queue_object(vthread_t thr, vvp_
|
||||||
return dqueue;
|
return dqueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following are used to allow a common template to be written for
|
||||||
|
* queue real/string/vec4 operations
|
||||||
|
*/
|
||||||
|
inline static void pop_value(double&value, vthread_t thr, unsigned)
|
||||||
|
{
|
||||||
|
value = thr->pop_real();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void pop_value(string&value, vthread_t thr, unsigned)
|
||||||
|
{
|
||||||
|
value = thr->pop_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void pop_value(vvp_vector4_t&value, vthread_t thr, unsigned wid)
|
||||||
|
{
|
||||||
|
value = thr->pop_vec4();
|
||||||
|
assert(value.size() == wid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following are used to allow the queue templates to print correctly.
|
||||||
|
*/
|
||||||
|
static void print_queue_type(double)
|
||||||
|
{
|
||||||
|
cerr << "queue<real>";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_queue_type(string)
|
||||||
|
{
|
||||||
|
cerr << "queue<string>";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_queue_type(vvp_vector4_t value)
|
||||||
|
{
|
||||||
|
cerr << "queue<vector[" << value.size() << "]>";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_queue_value(double value)
|
||||||
|
{
|
||||||
|
cerr << value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_queue_value(string value)
|
||||||
|
{
|
||||||
|
cerr << "\"" << value << "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_queue_value(vvp_vector4_t value)
|
||||||
|
{
|
||||||
|
cerr << value;
|
||||||
|
}
|
||||||
|
|
||||||
template <class T> T coerce_to_width(const T&that, unsigned width)
|
template <class T> T coerce_to_width(const T&that, unsigned width)
|
||||||
{
|
{
|
||||||
if (that.size() == width)
|
if (that.size() == width)
|
||||||
|
|
@ -5084,27 +5138,40 @@ bool of_PUTC_STR_VEC4(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ELEM, class QTYPE>
|
||||||
|
static bool qinsert(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
||||||
|
{
|
||||||
|
int64_t idx = thr->words[3].w_int;
|
||||||
|
ELEM value;
|
||||||
|
vvp_net_t*net = cp->net;
|
||||||
|
unsigned max_size = thr->words[cp->bit_idx[0]].w_int;
|
||||||
|
pop_value(value, thr, wid); // Pop the value to store.
|
||||||
|
|
||||||
|
vvp_queue*queue = get_queue_object<QTYPE>(thr, net);
|
||||||
|
assert(queue);
|
||||||
|
if (idx < 0) {
|
||||||
|
cerr << "Warning: cannot insert at a negative ";
|
||||||
|
print_queue_type(value);
|
||||||
|
cerr << " index (" << idx << "). ";
|
||||||
|
print_queue_value(value);
|
||||||
|
cerr << " was not added." << endl;
|
||||||
|
} else if (thr->flags[4] != BIT4_0) {
|
||||||
|
cerr << "Warning: cannot insert at an undefined ";
|
||||||
|
print_queue_type(value);
|
||||||
|
cerr << " index. ";
|
||||||
|
print_queue_value(value);
|
||||||
|
cerr << " was not added." << endl;
|
||||||
|
} else
|
||||||
|
queue->insert(idx, value, max_size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* %qinsert/real <var-label>
|
* %qinsert/real <var-label>
|
||||||
*/
|
*/
|
||||||
bool of_QINSERT_REAL(vthread_t thr, vvp_code_t cp)
|
bool of_QINSERT_REAL(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
int64_t idx = thr->words[3].w_int;
|
return qinsert<double, vvp_queue_real>(thr, cp);
|
||||||
vvp_net_t*net = cp->net;
|
|
||||||
double value = thr->pop_real(); // Pop the real value to be inserted.
|
|
||||||
unsigned max_size = thr->words[cp->bit_idx[0]].w_int;
|
|
||||||
|
|
||||||
vvp_queue*queue = get_queue_object<vvp_queue_real>(thr, net);
|
|
||||||
assert(queue);
|
|
||||||
if (idx < 0)
|
|
||||||
cerr << "Warning: cannot insert at a negative queue<real> index ("
|
|
||||||
<< idx << "). " << value << " was not added." << endl;
|
|
||||||
else if (thr->flags[4] != BIT4_0)
|
|
||||||
cerr << "Warning: cannot insert at an undefined queue<real> index. "
|
|
||||||
<< value << " was not added." << endl;
|
|
||||||
else
|
|
||||||
queue->insert(idx, value, max_size);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -5112,22 +5179,7 @@ bool of_QINSERT_REAL(vthread_t thr, vvp_code_t cp)
|
||||||
*/
|
*/
|
||||||
bool of_QINSERT_STR(vthread_t thr, vvp_code_t cp)
|
bool of_QINSERT_STR(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
int64_t idx = thr->words[3].w_int;
|
return qinsert<string, vvp_queue_string>(thr, cp);
|
||||||
vvp_net_t*net = cp->net;
|
|
||||||
string value = thr->pop_str(); // Pop the string to be stored...
|
|
||||||
unsigned max_size = thr->words[cp->bit_idx[0]].w_int;
|
|
||||||
|
|
||||||
vvp_queue*queue = get_queue_object<vvp_queue_string>(thr, net);
|
|
||||||
assert(queue);
|
|
||||||
if (idx < 0)
|
|
||||||
cerr << "Warning: cannot insert at a negative queue<string> index ("
|
|
||||||
<< idx << "). \"" << value << "\" was not added." << endl;
|
|
||||||
else if (thr->flags[4] != BIT4_0)
|
|
||||||
cerr << "Warning: cannot insert at an undefined queue<string> index. \""
|
|
||||||
<< value << "\" was not added." << endl;
|
|
||||||
else
|
|
||||||
queue->insert(idx, value, max_size);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -5135,27 +5187,7 @@ bool of_QINSERT_STR(vthread_t thr, vvp_code_t cp)
|
||||||
*/
|
*/
|
||||||
bool of_QINSERT_V(vthread_t thr, vvp_code_t cp)
|
bool of_QINSERT_V(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
int64_t idx = thr->words[3].w_int;
|
return qinsert<vvp_vector4_t, vvp_queue_vec4>(thr, cp, cp->bit_idx[1]);
|
||||||
vvp_net_t*net = cp->net;
|
|
||||||
vvp_vector4_t value = thr->pop_vec4(); // Pop the vector4 value to be store...
|
|
||||||
unsigned max_size = thr->words[cp->bit_idx[0]].w_int;
|
|
||||||
unsigned wid = cp->bit_idx[1];
|
|
||||||
|
|
||||||
assert(value.size() == wid);
|
|
||||||
|
|
||||||
vvp_queue*queue = get_queue_object<vvp_queue_vec4>(thr, net);
|
|
||||||
assert(queue);
|
|
||||||
if (idx < 0)
|
|
||||||
cerr << "Warning: cannot insert at a negative queue<vector["
|
|
||||||
<< value.size() << "]> index (" << idx << "). " << value
|
|
||||||
<< " was not added." << endl;
|
|
||||||
else if (thr->flags[4] != BIT4_0)
|
|
||||||
cerr << "Warning: cannot insert at an undefined queue<vector["
|
|
||||||
<< value.size() << "]> index. " << value
|
|
||||||
<< " was not added." << endl;
|
|
||||||
else
|
|
||||||
queue->insert(idx, value, max_size);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -5958,26 +5990,6 @@ bool of_STORE_PROP_V(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The following are used to allow a common template to be written for
|
|
||||||
* queue real/string/vec4 operations
|
|
||||||
*/
|
|
||||||
static void pop_value(double&value, vthread_t thr, unsigned)
|
|
||||||
{
|
|
||||||
value = thr->pop_real();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pop_value(string&value, vthread_t thr, unsigned)
|
|
||||||
{
|
|
||||||
value = thr->pop_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pop_value(vvp_vector4_t&value, vthread_t thr, unsigned wid)
|
|
||||||
{
|
|
||||||
value = thr->pop_vec4();
|
|
||||||
assert(value.size() == wid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* %store/qb/r <var-label>, <max-idx>
|
* %store/qb/r <var-label>, <max-idx>
|
||||||
*/
|
*/
|
||||||
|
|
@ -6031,43 +6043,10 @@ bool of_STORE_QB_V(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The following are used to allow the template to print correctly.
|
|
||||||
*/
|
|
||||||
static void print_queue_type(double)
|
|
||||||
{
|
|
||||||
cerr << "queue<real>";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_queue_type(string)
|
|
||||||
{
|
|
||||||
cerr << "queue<string>";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_queue_type(vvp_vector4_t value)
|
|
||||||
{
|
|
||||||
cerr << "queue<vector[" << value.size() << "]>";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_queue_value(double value)
|
|
||||||
{
|
|
||||||
cerr << value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_queue_value(string value)
|
|
||||||
{
|
|
||||||
cerr << "\"" << value << "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_queue_value(vvp_vector4_t value)
|
|
||||||
{
|
|
||||||
cerr << value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ELEM, class QTYPE>
|
template <typename ELEM, class QTYPE>
|
||||||
static bool store_qdar(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
static bool store_qdar(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
||||||
{
|
{
|
||||||
int64_t adr = thr->words[3].w_int;
|
int64_t idx = thr->words[3].w_int;
|
||||||
ELEM value;
|
ELEM value;
|
||||||
vvp_net_t*net = cp->net;
|
vvp_net_t*net = cp->net;
|
||||||
unsigned max_size = thr->words[cp->bit_idx[0]].w_int;
|
unsigned max_size = thr->words[cp->bit_idx[0]].w_int;
|
||||||
|
|
@ -6075,10 +6054,10 @@ static bool store_qdar(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
||||||
|
|
||||||
vvp_queue*queue = get_queue_object<QTYPE>(thr, net);
|
vvp_queue*queue = get_queue_object<QTYPE>(thr, net);
|
||||||
assert(queue);
|
assert(queue);
|
||||||
if (adr < 0) {
|
if (idx < 0) {
|
||||||
cerr << "Warning: cannot assign to a negative ";
|
cerr << "Warning: cannot assign to a negative ";
|
||||||
print_queue_type(value);
|
print_queue_type(value);
|
||||||
cerr << " index (" << adr << "). ";
|
cerr << " index (" << idx << "). ";
|
||||||
print_queue_value(value);
|
print_queue_value(value);
|
||||||
cerr << " was not added." << endl;
|
cerr << " was not added." << endl;
|
||||||
} else if (thr->flags[4] != BIT4_0) {
|
} else if (thr->flags[4] != BIT4_0) {
|
||||||
|
|
@ -6088,7 +6067,7 @@ static bool store_qdar(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
||||||
print_queue_value(value);
|
print_queue_value(value);
|
||||||
cerr << " was not added." << endl;
|
cerr << " was not added." << endl;
|
||||||
} else
|
} else
|
||||||
queue->set_word_max(adr, value, max_size);
|
queue->set_word_max(idx, value, max_size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue