vec4 stack versions of queue pop methods.

This commit is contained in:
Stephen Williams 2014-10-24 09:03:20 -07:00
parent 24b8752475
commit 4588f7c615
6 changed files with 163 additions and 94 deletions

View File

@ -738,7 +738,8 @@ static void draw_select_vec4(ivl_expr_t expr)
if (ivl_expr_value(subexpr)==IVL_VT_DARRAY) {
ivl_signal_t sig = ivl_expr_signal(subexpr);
assert(sig);
assert(ivl_signal_data_type(sig)==IVL_VT_DARRAY);
assert( (ivl_signal_data_type(sig)==IVL_VT_DARRAY)
|| (ivl_signal_data_type(sig)==IVL_VT_QUEUE) );
assert(base);
draw_eval_expr_into_integer(base, 3);
@ -773,6 +774,27 @@ static void draw_select_pad_vec4(ivl_expr_t expr, int stuff_ok_flag)
fprintf(vvp_out, " %%pad/u %u;\n", wid);
}
/*
* This function handles the speical case of a call to the internal
* functions $ivl_darray_method$pop_back et al. The first (and only)
* argument is the signal that represents a dynamic queue. Generate a
* %qpop instruction to pop a value and push it to the vec4 stack.
*/
static void draw_darray_pop(ivl_expr_t expr)
{
const char*fb;
if (strcmp(ivl_expr_name(expr), "$ivl_darray_method$pop_back")==0)
fb = "b";
else
fb = "f";
ivl_expr_t arg = ivl_expr_parm(expr, 0);
assert(ivl_expr_type(arg) == IVL_EX_SIGNAL);
fprintf(vvp_out, " %%qpop/%s/v v%p_0;\n", fb, ivl_expr_signal(arg));
}
static void draw_sfunc_vec4(ivl_expr_t expr)
{
unsigned parm_count = ivl_expr_parms(expr);
@ -790,6 +812,15 @@ static void draw_sfunc_vec4(ivl_expr_t expr)
return;
}
if (strcmp(ivl_expr_name(expr), "$ivl_darray_method$pop_back")==0) {
draw_darray_pop(expr);
return;
}
if (strcmp(ivl_expr_name(expr),"$ivl_darray_method$pop_front")==0) {
draw_darray_pop(expr);
return;
}
draw_vpi_func_call(expr);
}

View File

@ -1823,7 +1823,6 @@ static int show_push_frontback_method(ivl_statement_t net)
ivl_type_t element_type = ivl_type_element(var_type);
ivl_expr_t parm1 = ivl_stmt_parm(net,1);
struct vector_info vec;
switch (ivl_type_base(element_type)) {
case IVL_VT_REAL:
draw_eval_real(parm1);
@ -1834,10 +1833,9 @@ static int show_push_frontback_method(ivl_statement_t net)
fprintf(vvp_out, " %%store/%s/str v%p_0;\n", type_code, var);
break;
default:
vec = draw_eval_expr_wid(parm1, width_of_packed_type(element_type), STUFF_OK_RO);
fprintf(vvp_out, " %%set/%s v%p_0, %u, %u;\n",
type_code, var, vec.base, vec.wid);
if (vec.base >= 4) clr_vector(vec);
draw_eval_vec4(parm1, STUFF_OK_XZ);
fprintf(vvp_out, " %%store/%s/v v%p_0, %u;\n",
type_code, var, width_of_packed_type(element_type));
break;
}

View File

@ -186,10 +186,10 @@ extern bool of_POP_VEC4(vthread_t thr, vvp_code_t code);
extern bool of_POW(vthread_t thr, vvp_code_t code);
extern bool of_POW_S(vthread_t thr, vvp_code_t code);
extern bool of_POW_WR(vthread_t thr, vvp_code_t code);
extern bool of_QPOP_B(vthread_t thr, vvp_code_t code);
extern bool of_QPOP_F(vthread_t thr, vvp_code_t code);
extern bool of_QPOP_B_STR(vthread_t thr, vvp_code_t code);
extern bool of_QPOP_B_V(vthread_t thr, vvp_code_t code);
extern bool of_QPOP_F_STR(vthread_t thr, vvp_code_t code);
extern bool of_QPOP_F_V(vthread_t thr, vvp_code_t code);
extern bool of_PROP_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_PROP_R(vthread_t thr, vvp_code_t code);
extern bool of_PROP_STR(vthread_t thr, vvp_code_t code);
@ -223,8 +223,10 @@ extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code);
extern bool of_STORE_DAR_VEC4(vthread_t thr, vvp_code_t code);
extern bool of_STORE_QB_R(vthread_t thr, vvp_code_t code);
extern bool of_STORE_QB_STR(vthread_t thr, vvp_code_t code);
extern bool of_STORE_QB_V(vthread_t thr, vvp_code_t code);
extern bool of_STORE_QF_R(vthread_t thr, vvp_code_t code);
extern bool of_STORE_QF_STR(vthread_t thr, vvp_code_t code);
extern bool of_STORE_QF_V(vthread_t thr, vvp_code_t code);
extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_STORE_OBJA(vthread_t thr, vvp_code_t code);
extern bool of_STORE_PROP_OBJ(vthread_t thr, vvp_code_t code);

View File

@ -243,10 +243,10 @@ static const struct opcode_table_s opcode_table[] = {
{ "%pushi/vec4",of_PUSHI_VEC4,3,{OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pushv/str", of_PUSHV_STR, 2, {OA_BIT1,OA_BIT2, OA_NONE} },
{ "%putc/str/vec4",of_PUTC_STR_VEC4,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} },
{ "%qpop/b", of_QPOP_B, 3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
{ "%qpop/b/str",of_QPOP_B_STR,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%qpop/f", of_QPOP_F, 3,{OA_FUNC_PTR,OA_BIT1, OA_BIT2} },
{ "%qpop/b/v", of_QPOP_B_V, 1,{OA_FUNC_PTR,OA_NONE, OA_BIT2} },
{ "%qpop/f/str",of_QPOP_F_STR,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%qpop/f/v", of_QPOP_F_V, 1,{OA_FUNC_PTR,OA_NONE, OA_BIT2} },
{ "%release/net",of_RELEASE_NET,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
{ "%release/reg",of_RELEASE_REG,3,{OA_FUNC_PTR,OA_BIT1,OA_BIT2} },
{ "%release/wr", of_RELEASE_WR, 2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} },
@ -276,8 +276,10 @@ static const struct opcode_table_s opcode_table[] = {
{ "%store/prop/v", of_STORE_PROP_V, 2, {OA_NUMBER, OA_BIT1, OA_NONE} },
{ "%store/qb/r", of_STORE_QB_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/qb/str", of_STORE_QB_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/qb/v", of_STORE_QB_V, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ "%store/qf/r", of_STORE_QF_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/qf/str", of_STORE_QF_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/qf/v", of_STORE_QF_V, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} },
{ "%store/real", of_STORE_REAL, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%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} },

View File

@ -1102,6 +1102,11 @@ character of the string variable at <functtor-label>. This is
basically an implementation of <string>.putc(<muxr>, <val>) where
<val> is the 8bit vector popped from the stack.
* %qpop/b/v <functor-label>
* %qpop/f/v <functor-label>
Pop values from a dynamic queue object.
* %release/net <functor-label>, <base>, <width>
* %release/reg <functor-label>, <base>, <width>
@ -1266,8 +1271,10 @@ index in the index register <index>
* %store/dar/vec4 <var-label>
* %store/qf/r <var-label>
* %store/qf/str <var-label>
* %store/qf/v <var-label>, <wid>
* %store/qb/r <var-label>
* %store/qb/str <var-label>
* %store/qf/v <var-label>, <wid>
The %store/str instruction pops the top of the string stack and writes
it to the string variable.

View File

@ -388,6 +388,30 @@ const vvp_vector4_t& vthread_get_vec4_stack(struct vthread_s*thr, unsigned depth
return thr->peek_vec4(depth);
}
/*
* This is a function to get a vvp_queue handle from the variable
* referenced by "net". If the queue is nil, then allocated it and
* assign the value to the net. Note that this function is
* parameterized by the queue type so that we can create the right
* derived type of queue object.
*/
template <class VVP_QUEUE> static vvp_queue*get_queue_object(vthread_t thr, vvp_net_t*net)
{
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
if (dqueue == 0) {
assert(obj->get_object().test_nil());
dqueue = new VVP_QUEUE;
vvp_object_t val (dqueue);
vvp_net_ptr_t ptr (net, 0);
vvp_send_object(ptr, val, thr->wt_context);
}
return dqueue;
}
template <class T> T coerce_to_width(const T&that, unsigned width)
{
if (that.size() == width)
@ -5441,75 +5465,11 @@ bool of_PUTC_STR_VEC4(vthread_t thr, vvp_code_t cp)
return true;
}
/*
* %qpop/b <var-label>, <bit>, <wid>
*/
bool of_QPOP_B(vthread_t thr, vvp_code_t cp)
{
unsigned bit = cp->bit_idx[0];
unsigned wid = cp->bit_idx[1];
vvp_net_t*net = cp->net;
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
vvp_vector4_t value;
dqueue->get_word(size-1, value);
dqueue->pop_back();
assert(value.size() == wid);
#if 0
thr->bits4.set_vec(bit, value);
#else
fprintf(stderr, "%%qpop/b <label>, %u, %u; NOT IMPLEMENTED\n", bit, wid);
#endif
return true;
}
/*
* %qpop/f <var-label>, <bit>, <wid>
*/
bool of_QPOP_F(vthread_t thr, vvp_code_t cp)
{
unsigned bit = cp->bit_idx[0];
unsigned wid = cp->bit_idx[1];
vvp_net_t*net = cp->net;
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
vvp_vector4_t value;
dqueue->get_word(0, value);
dqueue->pop_front();
assert(value.size() == wid);
#if 0
thr->bits4.set_vec(bit, value);
#else
fprintf(stderr, "%%qpop/f <label>, %u, %u; NOT IMPLEMENTED\n", bit, wid);
#endif
return true;
}
bool of_QPOP_B_STR(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
vvp_queue*dqueue = get_queue_object<vvp_queue_string>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
@ -5523,13 +5483,32 @@ bool of_QPOP_B_STR(vthread_t thr, vvp_code_t cp)
return true;
}
/*
* %qpop/b/v <var-label>
*/
bool of_QPOP_B_V(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_queue*dqueue = get_queue_object<vvp_queue_vec4>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
vvp_vector4_t value;
dqueue->get_word(size-1, value);
dqueue->pop_back();
thr->push_vec4(value);
return true;
}
bool of_QPOP_F_STR(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
vvp_queue*dqueue = get_queue_object<vvp_queue_string>(thr, net);
assert(dqueue);
string value;
@ -5540,6 +5519,27 @@ bool of_QPOP_F_STR(vthread_t thr, vvp_code_t cp)
return true;
}
/*
* %qpop/f/v <var-label>
*/
bool of_QPOP_F_V(vthread_t thr, vvp_code_t cp)
{
vvp_net_t*net = cp->net;
vvp_queue*dqueue = get_queue_object<vvp_queue_vec4>(thr, net);
assert(dqueue);
size_t size = dqueue->get_size();
assert(size > 0);
vvp_vector4_t value;
dqueue->get_word(0, value);
dqueue->pop_front();
thr->push_vec4(value);
return true;
}
/*
* These implement the %release/net and %release/reg instructions. The
* %release/net instruction applies to a net kind of functor by
@ -5739,11 +5739,11 @@ bool of_SET_DAR_OBJ_VEC4(vthread_t thr, vvp_code_t cp)
/*
* %set/qb <var-label> <bit>, <wid>
*/
bool of_SET_QB(vthread_t thr, vvp_code_t cp)
bool of_SET_QB(vthread_t /*thr*/, vvp_code_t /*cp*/)
{
#if 0
unsigned bit = cp->bit_idx[0];
unsigned wid = cp->bit_idx[1];
#if 0
/* Make a vector of the desired width. */
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
@ -5771,11 +5771,11 @@ bool of_SET_QB(vthread_t thr, vvp_code_t cp)
/*
* %set/qf <var-label> <bit>, <wid>
*/
bool of_SET_QF(vthread_t thr, vvp_code_t cp)
bool of_SET_QF(vthread_t /*thr*/, vvp_code_t /*cp*/)
{
#if 0
unsigned bit = cp->bit_idx[0];
unsigned wid = cp->bit_idx[1];
#if 0
/* Make a vector of the desired width. */
vvp_vector4_t value = vthread_bits_to_vector(thr, bit, wid);
@ -6228,24 +6228,34 @@ bool of_STORE_QB_STR(vthread_t thr, vvp_code_t cp)
string value = thr->pop_str();
vvp_net_t*net = cp->net;
vvp_fun_signal_object*obj = dynamic_cast<vvp_fun_signal_object*> (net->fun);
assert(obj);
vvp_queue*dqueue = obj->get_object().peek<vvp_queue>();
if (dqueue == 0) {
assert(obj->get_object().test_nil());
dqueue = new vvp_queue_string;
vvp_object_t val (dqueue);
vvp_net_ptr_t ptr (cp->net, 0);
vvp_send_object(ptr, val, thr->wt_context);
}
vvp_queue*dqueue = get_queue_object<vvp_queue_string>(thr, net);
assert(dqueue);
dqueue->push_back(value);
return true;
}
/*
* %store/qb/v <var-label>, <wid>
*/
bool of_STORE_QB_V(vthread_t thr, vvp_code_t cp)
{
// Pop the vec4 value to be stored...
vvp_vector4_t value = thr->pop_vec4();
vvp_net_t*net = cp->net;
unsigned wid = cp->bit_idx[0];
assert(value.size() == wid);
vvp_queue*dqueue = get_queue_object<vvp_queue_vec4>(thr, net);
assert(dqueue);
dqueue->push_back(value);
return true;
}
/*
* %store/qf/r <var-label>
*/
@ -6264,6 +6274,25 @@ bool of_STORE_QF_STR(vthread_t, vvp_code_t)
return true;
}
/*
* %store/qb/v <var-label>, <wid>
*/
bool of_STORE_QF_V(vthread_t thr, vvp_code_t cp)
{
// Pop the vec4 value to be stored...
vvp_vector4_t value = thr->pop_vec4();
vvp_net_t*net = cp->net;
unsigned wid = cp->bit_idx[0];
vvp_queue*dqueue = get_queue_object<vvp_queue_vec4>(thr, net);
assert(value.size() == wid);
assert(dqueue);
dqueue->push_front(value);
return true;
}
bool of_STORE_REAL(vthread_t thr, vvp_code_t cp)
{
double val = thr->pop_real();