Code generation and runtime for class shallow copy.

This commit is contained in:
Stephen Williams 2013-04-28 10:10:36 -07:00
parent 8e559e4e91
commit ac78ba588f
10 changed files with 106 additions and 0 deletions

View File

@ -90,6 +90,23 @@ static int eval_object_property(ivl_expr_t expr)
return 0;
}
static int eval_object_shallowcopy(ivl_expr_t ex)
{
ivl_expr_t dest = ivl_expr_oper1(ex);
ivl_expr_t src = ivl_expr_oper2(ex);
draw_eval_object(dest);
draw_eval_object(src);
/* The %scopy opcode pops the top of the object stack as the
source object, and shallow-copies it to the new top, the
destination object. The destination is left on the top of
the stack. */
fprintf(vvp_out, " %%scopy;\n");
return 0;
}
static int eval_object_signal(ivl_expr_t ex)
{
ivl_signal_t sig = ivl_expr_signal(ex);
@ -125,6 +142,9 @@ int draw_eval_object(ivl_expr_t ex)
case IVL_EX_PROPERTY:
return eval_object_property(ex);
case IVL_EX_SHALLOWCOPY:
return eval_object_shallowcopy(ex);
case IVL_EX_SIGNAL:
return eval_object_signal(ex);

View File

@ -59,6 +59,9 @@ class class_property_t {
virtual void set_object(char*buf, const vvp_object_t&val);
virtual void get_object(char*buf, vvp_object_t&val);
// Implement polymorphic shallow copy.
virtual void copy(char*buf, char*src) = 0;
protected:
size_t offset_;
};
@ -134,6 +137,8 @@ template <class T> class property_atom : public class_property_t {
void set_vec4(char*buf, const vvp_vector4_t&val);
void get_vec4(char*buf, vvp_vector4_t&val);
void copy(char*dst, char*src);
};
template <class T> class property_real : public class_property_t {
@ -151,6 +156,8 @@ template <class T> class property_real : public class_property_t {
void set_real(char*buf, double val);
double get_real(char*buf);
void copy(char*dst, char*src);
};
class property_string : public class_property_t {
@ -171,6 +178,8 @@ class property_string : public class_property_t {
void set_string(char*buf, const string&);
string get_string(char*buf);
void copy(char*dst, char*src);
};
class property_object : public class_property_t {
@ -191,6 +200,8 @@ class property_object : public class_property_t {
void set_object(char*buf, const vvp_object_t&);
void get_object(char*buf, vvp_object_t&);
void copy(char*dst, char*src);
};
template <class T> void property_atom<T>::set_vec4(char*buf, const vvp_vector4_t&val)
@ -216,6 +227,13 @@ template <class T> void property_atom<T>::get_vec4(char*buf, vvp_vector4_t&val)
val.setarray(0, val.size(), tmp);
}
template <class T> void property_atom<T>::copy(char*dst, char*src)
{
T*dst_obj = reinterpret_cast<T*> (dst+offset_);
T*src_obj = reinterpret_cast<T*> (src+offset_);
*dst_obj = *src_obj;
}
template <class T> void property_real<T>::set_real(char*buf, double val)
{
T*tmp = reinterpret_cast<T*>(buf+offset_);
@ -228,6 +246,13 @@ template <class T> double property_real<T>::get_real(char*buf)
return *tmp;
}
template <class T> void property_real<T>::copy(char*dst, char*src)
{
T*dst_obj = reinterpret_cast<T*> (dst+offset_);
T*src_obj = reinterpret_cast<T*> (src+offset_);
*dst_obj = *src_obj;
}
void property_string::set_string(char*buf, const string&val)
{
string*tmp = reinterpret_cast<string*>(buf+offset_);
@ -240,6 +265,13 @@ string property_string::get_string(char*buf)
return *tmp;
}
void property_string::copy(char*dst, char*src)
{
string*dst_obj = reinterpret_cast<string*> (dst+offset_);
string*src_obj = reinterpret_cast<string*> (src+offset_);
*dst_obj = *src_obj;
}
void property_object::set_object(char*buf, const vvp_object_t&val)
{
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
@ -252,6 +284,12 @@ void property_object::get_object(char*buf, vvp_object_t&val)
val = *tmp;
}
void property_object::copy(char*dst, char*src)
{
vvp_object_t*dst_obj = reinterpret_cast<vvp_object_t*>(dst);
vvp_object_t*src_obj = reinterpret_cast<vvp_object_t*>(src);
*dst_obj = *src_obj;
}
/* **** */
@ -404,6 +442,16 @@ void class_type::get_object(class_type::inst_t obj, size_t pid, vvp_object_t&val
properties_[pid].type->get_object(buf, val);
}
void class_type::copy_property(class_type::inst_t dst, size_t pid, class_type::inst_t src) const
{
char*dst_buf = reinterpret_cast<char*> (dst);
char*src_buf = reinterpret_cast<char*> (src);
assert(pid < properties_.size());
properties_[pid].type->copy(dst_buf, src_buf);
}
int class_type::get_type_code(void) const
{
return vpiClassDefn;

View File

@ -68,6 +68,8 @@ class class_type : public __vpiHandle {
void set_object(inst_t inst, size_t pid, const vvp_object_t&val) const;
void get_object(inst_t inst, size_t pid, vvp_object_t&val) const;
void copy_property(inst_t dst, size_t idx, inst_t src) const;
public: // VPI related methods
int get_type_code(void) const;

View File

@ -176,6 +176,7 @@ extern bool of_PUTC_STR_V(vthread_t thr, vvp_code_t code);
extern bool of_RELEASE_NET(vthread_t thr, vvp_code_t code);
extern bool of_RELEASE_REG(vthread_t thr, vvp_code_t code);
extern bool of_RELEASE_WR(vthread_t thr, vvp_code_t code);
extern bool of_SCOPY(vthread_t thr, vvp_code_t code);
extern bool of_SET_AV(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR(vthread_t thr, vvp_code_t code);
extern bool of_SET_VEC(vthread_t thr, vvp_code_t code);

View File

@ -224,6 +224,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%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} },
{ "%scopy", of_SCOPY, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%set/av", of_SET_AV, 3, {OA_ARR_PTR, OA_BIT1, OA_BIT2} },
{ "%set/dar",of_SET_DAR,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%set/v", of_SET_VEC,3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },

View File

@ -4809,6 +4809,17 @@ bool of_RELEASE_WR(vthread_t, vvp_code_t cp)
return true;
}
bool of_SCOPY(vthread_t thr, vvp_code_t)
{
vvp_object_t tmp;
thr->pop_object(tmp);
vvp_object_t&dest = thr->peek_object();
dest.shallow_copy(tmp);
return true;
}
/*
* This implements the "%set/av <label>, <bit>, <wid>" instruction. In
* this case, the <label> is an array label, and the <bit> and <wid>

View File

@ -74,3 +74,15 @@ void vvp_cobject::get_object(size_t pid, vvp_object_t&val)
{
return defn_->get_object(properties_, pid, val);
}
void vvp_cobject::shallow_copy(const vvp_object*obj)
{
const vvp_cobject*that = dynamic_cast<const vvp_cobject*>(obj);
assert(that);
assert(defn_ == that->defn_);
for (size_t idx = 0 ; idx < defn_->property_count() ; idx += 1)
defn_->copy_property(properties_, idx, that->properties_);
}

View File

@ -44,6 +44,8 @@ class vvp_cobject : public vvp_object {
void set_object(size_t pid, const vvp_object_t&val);
void get_object(size_t pid, vvp_object_t&val);
void shallow_copy(const vvp_object*that);
private:
const class_type* defn_;
// For now, only support 32bit bool signed properties.

View File

@ -34,3 +34,8 @@ vvp_object::~vvp_object()
{
total_active_cnt_ -= 1;
}
void vvp_object::shallow_copy(const vvp_object*that)
{
assert(0);
}

View File

@ -32,6 +32,8 @@ class vvp_object {
inline vvp_object() { ref_cnt_ = 0; total_active_cnt_ += 1; }
virtual ~vvp_object() =0;
virtual void shallow_copy(const vvp_object*that);
static void cleanup(void);
private:
@ -59,6 +61,8 @@ class vvp_object_t {
inline bool operator != (const vvp_object_t&that) const
{ return ref_ != that.ref_; }
inline void shallow_copy(const vvp_object_t&that)
{ ref_->shallow_copy(that.ref_); }
template <class T> T*peek(void) const;
private: