Refactor load DAR routines
This commit is contained in:
parent
3993241d04
commit
294005c5b2
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-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
|
||||
|
|
@ -974,13 +974,13 @@ void vpip_execute_vpi_call(vthread_t thr, vpiHandle ref)
|
|||
/* If the function returns a value, then push the value
|
||||
to the appropriate thread stack. */
|
||||
if (sysfunc_real*func_real = dynamic_cast<sysfunc_real*>(ref)) {
|
||||
vthread_push_real(thr, func_real->return_value());
|
||||
vthread_push(thr, func_real->return_value());
|
||||
}
|
||||
else if (sysfunc_str*func_string = dynamic_cast<sysfunc_str*>(ref)) {
|
||||
vthread_push_str(thr, func_string->return_value());
|
||||
vthread_push(thr, func_string->return_value());
|
||||
}
|
||||
else if (sysfunc_vec4*func_vec4 = dynamic_cast<sysfunc_vec4*>(ref)) {
|
||||
vthread_push_vec4(thr, func_vec4->return_value());
|
||||
vthread_push(thr, func_vec4->return_value());
|
||||
}
|
||||
vpip_cur_task = 0;
|
||||
}
|
||||
|
|
|
|||
133
vvp/vthread.cc
133
vvp/vthread.cc
|
|
@ -388,24 +388,19 @@ string get_fileline()
|
|||
return running_thread->get_fileline();
|
||||
}
|
||||
|
||||
void vthread_push_vec4(struct vthread_s*thr, const vvp_vector4_t&val)
|
||||
{
|
||||
thr->push_vec4(val);
|
||||
}
|
||||
|
||||
void vthread_push_real(struct vthread_s*thr, double val)
|
||||
void vthread_push(struct vthread_s*thr, double val)
|
||||
{
|
||||
thr->push_real(val);
|
||||
}
|
||||
|
||||
void vthread_push_str(struct vthread_s*thr, const string&val)
|
||||
void vthread_push(struct vthread_s*thr, const string&val)
|
||||
{
|
||||
thr->push_str(val);
|
||||
}
|
||||
|
||||
void vthread_pop_vec4(struct vthread_s*thr, unsigned depth)
|
||||
void vthread_push(struct vthread_s*thr, const vvp_vector4_t&val)
|
||||
{
|
||||
thr->pop_vec4(depth);
|
||||
thr->push_vec4(val);
|
||||
}
|
||||
|
||||
void vthread_pop_real(struct vthread_s*thr, unsigned depth)
|
||||
|
|
@ -418,9 +413,9 @@ void vthread_pop_str(struct vthread_s*thr, unsigned depth)
|
|||
thr->pop_str(depth);
|
||||
}
|
||||
|
||||
const string&vthread_get_str_stack(struct vthread_s*thr, unsigned depth)
|
||||
void vthread_pop_vec4(struct vthread_s*thr, unsigned depth)
|
||||
{
|
||||
return thr->peek_str(depth);
|
||||
thr->pop_vec4(depth);
|
||||
}
|
||||
|
||||
double vthread_get_real_stack(struct vthread_s*thr, unsigned depth)
|
||||
|
|
@ -428,6 +423,11 @@ double vthread_get_real_stack(struct vthread_s*thr, unsigned depth)
|
|||
return thr->peek_real(depth);
|
||||
}
|
||||
|
||||
const string&vthread_get_str_stack(struct vthread_s*thr, unsigned depth)
|
||||
{
|
||||
return thr->peek_str(depth);
|
||||
}
|
||||
|
||||
const vvp_vector4_t& vthread_get_vec4_stack(struct vthread_s*thr, unsigned depth)
|
||||
{
|
||||
return thr->peek_vec4(depth);
|
||||
|
|
@ -464,23 +464,22 @@ template <class VVP_QUEUE> static vvp_queue*get_queue_object(vthread_t thr, vvp_
|
|||
* 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)
|
||||
inline static void pop_value(vthread_t thr, double&value, unsigned)
|
||||
{
|
||||
value = thr->pop_real();
|
||||
}
|
||||
|
||||
inline static void pop_value(string&value, vthread_t thr, unsigned)
|
||||
inline static void pop_value(vthread_t thr, string&value, unsigned)
|
||||
{
|
||||
value = thr->pop_str();
|
||||
}
|
||||
|
||||
inline static void pop_value(vvp_vector4_t&value, vthread_t thr, unsigned wid)
|
||||
inline static void pop_value(vthread_t thr, vvp_vector4_t&value, unsigned wid)
|
||||
{
|
||||
value = thr->pop_vec4();
|
||||
assert(value.size() == wid);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following are used to allow the queue templates to print correctly.
|
||||
*/
|
||||
|
|
@ -517,6 +516,25 @@ inline static void print_queue_value(vvp_vector4_t value)
|
|||
cerr << value;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following are used to get a darray/queue default value.
|
||||
*/
|
||||
inline static void dq_default(double&value, unsigned)
|
||||
{
|
||||
value = 0.0;
|
||||
}
|
||||
|
||||
inline static void dq_default(string&value, unsigned)
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
|
||||
inline static void dq_default(vvp_vector4_t&value, unsigned wid)
|
||||
{
|
||||
value = vvp_vector4_t(wid);
|
||||
}
|
||||
|
||||
|
||||
template <class T> T coerce_to_width(const T&that, unsigned width)
|
||||
{
|
||||
if (that.size() == width)
|
||||
|
|
@ -3816,54 +3834,43 @@ bool of_LOAD_AR(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %load/dar/r <array-label>;
|
||||
*/
|
||||
bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp)
|
||||
template <typename ELEM>
|
||||
static bool load_dar(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
int64_t adr = thr->words[3].w_int;
|
||||
vvp_net_t*net = cp->net;
|
||||
|
||||
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>();
|
||||
|
||||
double word;
|
||||
ELEM word;
|
||||
if (darray &&
|
||||
(adr >= 0) && (thr->flags[4] == BIT4_0)) // A defined address >= 0
|
||||
darray->get_word(adr, word);
|
||||
else
|
||||
word = 0.0;
|
||||
dq_default(word, obj->size());
|
||||
|
||||
thr->push_real(word);
|
||||
vthread_push(thr, word);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %load/dar/r <array-label>;
|
||||
*/
|
||||
bool of_LOAD_DAR_R(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
return load_dar<double>(thr, cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* %load/dar/str <array-label>;
|
||||
*/
|
||||
bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
int64_t adr = thr->words[3].w_int;
|
||||
vvp_net_t*net = cp->net;
|
||||
|
||||
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>();
|
||||
|
||||
string word;
|
||||
if (darray &&
|
||||
(adr >= 0) && (thr->flags[4] == BIT4_0)) // A defined address >= 0
|
||||
darray->get_word(adr, word);
|
||||
else
|
||||
word = "";
|
||||
|
||||
thr->push_str(word);
|
||||
return true;
|
||||
return load_dar<string>(thr, cp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3871,24 +3878,7 @@ bool of_LOAD_DAR_STR(vthread_t thr, vvp_code_t cp)
|
|||
*/
|
||||
bool of_LOAD_DAR_VEC4(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
int64_t adr = thr->words[3].w_int;
|
||||
vvp_net_t*net = cp->net;
|
||||
|
||||
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>();
|
||||
|
||||
vvp_vector4_t word;
|
||||
if (darray &&
|
||||
(adr >= 0) && (thr->flags[4] == BIT4_0)) // A defined address >= 0
|
||||
darray->get_word(adr, word);
|
||||
else
|
||||
word = vvp_vector4_t(obj->size());
|
||||
|
||||
thr->push_vec4(word);
|
||||
return true;
|
||||
return load_dar<vvp_vector4_t>(thr, cp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -5193,7 +5183,7 @@ static bool qinsert(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
|||
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.
|
||||
pop_value(thr, value, wid); // Pop the value to store.
|
||||
|
||||
vvp_queue*queue = get_queue_object<QTYPE>(thr, net);
|
||||
assert(queue);
|
||||
|
|
@ -5242,21 +5232,6 @@ bool of_QINSERT_V(vthread_t thr, vvp_code_t cp)
|
|||
/*
|
||||
* Helper functions used in the queue pop templates
|
||||
*/
|
||||
inline static void qdefault(double&value, unsigned)
|
||||
{
|
||||
value = 0.0;
|
||||
}
|
||||
|
||||
inline static void qdefault(string&value, unsigned)
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
|
||||
inline static void qdefault(vvp_vector4_t&value, unsigned wid)
|
||||
{
|
||||
value = vvp_vector4_t(wid);
|
||||
}
|
||||
|
||||
inline void push_value(vthread_t thr, double value, unsigned)
|
||||
{
|
||||
thr->push_real(value);
|
||||
|
|
@ -5289,7 +5264,7 @@ static bool q_pop(vthread_t thr, vvp_code_t cp,
|
|||
if (size) {
|
||||
get_val_func(queue, value);
|
||||
} else {
|
||||
qdefault(value, wid);
|
||||
dq_default(value, wid);
|
||||
cerr << thr->get_fileline()
|
||||
<< "Warning: pop_" << loc << "() on empty "
|
||||
<< get_queue_type(value) << "." << endl;
|
||||
|
|
@ -6033,7 +6008,7 @@ static bool store_qb(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
|||
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.
|
||||
pop_value(thr, value, wid); // Pop the value to store.
|
||||
|
||||
vvp_queue*queue = get_queue_object<QTYPE>(thr, net);
|
||||
assert(queue);
|
||||
|
|
@ -6072,7 +6047,7 @@ static bool store_qdar(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
|||
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.
|
||||
pop_value(thr, value, wid); // Pop the value to store.
|
||||
|
||||
vvp_queue*queue = get_queue_object<QTYPE>(thr, net);
|
||||
assert(queue);
|
||||
|
|
@ -6124,7 +6099,7 @@ static bool store_qf(vthread_t thr, vvp_code_t cp, unsigned wid=0)
|
|||
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.
|
||||
pop_value(thr, value, wid); // Pop the value to store.
|
||||
|
||||
vvp_queue*queue = get_queue_object<QTYPE>(thr, net);
|
||||
assert(queue);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef IVL_vthread_H
|
||||
#define IVL_vthread_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-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
|
||||
|
|
@ -112,9 +112,9 @@ extern vvp_context_item_t vthread_get_rd_context_item(unsigned context_idx);
|
|||
/*
|
||||
* Access value stacks from thread space.
|
||||
*/
|
||||
extern void vthread_push_vec4(struct vthread_s*thr, const vvp_vector4_t&val);
|
||||
extern void vthread_push_str(struct vthread_s*thr, const std::string&val);
|
||||
extern void vthread_push_real(struct vthread_s*thr, double val);
|
||||
extern void vthread_push(struct vthread_s*thr, const vvp_vector4_t&val);
|
||||
extern void vthread_push(struct vthread_s*thr, const std::string&val);
|
||||
extern void vthread_push(struct vthread_s*thr, double val);
|
||||
|
||||
extern void vthread_pop_vec4(struct vthread_s*thr, unsigned count);
|
||||
extern void vthread_pop_str(struct vthread_s*thr, unsigned count);
|
||||
|
|
|
|||
Loading…
Reference in New Issue