Handle real value class properties.

As a side effect, this also adds support for 64bit integers.
This commit is contained in:
Stephen Williams 2013-01-10 18:48:15 -08:00
parent 2ea5919a4a
commit 106850ca7d
20 changed files with 347 additions and 52 deletions

View File

@ -109,7 +109,8 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \ load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
net_design.o netclass.o netdarray.o \ net_design.o netclass.o netdarray.o \
netenum.o netparray.o netstruct.o netvector.o net_event.o net_expr.o net_func.o \ netenum.o netparray.o netscalar.o netstruct.o netvector.o \
net_event.o net_expr.o net_func.o \
net_func_eval.o net_link.o net_modulo.o \ net_func_eval.o net_link.o net_modulo.o \
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \ net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \ net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -19,6 +19,7 @@
# include "pform_types.h" # include "pform_types.h"
# include "netlist.h" # include "netlist.h"
# include "netscalar.h"
# include "netvector.h" # include "netvector.h"
# include <typeinfo> # include <typeinfo>
# include "ivl_assert.h" # include "ivl_assert.h"
@ -37,6 +38,12 @@ ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*) const
ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
{ {
switch (type_code) { switch (type_code) {
case 64:
if (signed_flag)
return &netvector_t::atom2s64;
else
return &netvector_t::atom2u64;
case 32: case 32:
if (signed_flag) if (signed_flag)
return &netvector_t::atom2s32; return &netvector_t::atom2s32;
@ -62,3 +69,14 @@ ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
return 0; return 0;
} }
} }
ivl_type_s* real_type_t::elaborate_type(Design*, NetScope*) const
{
switch (type_code) {
case REAL:
return &netreal_t::type_real;
case SHORTREAL:
return &netreal_t::type_shortreal;
}
return 0;
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2011 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -364,6 +364,15 @@ NetEProperty::~NetEProperty()
{ {
} }
ivl_variable_type_t NetEProperty::expr_type() const
{
const netclass_t*use_type = dynamic_cast<const netclass_t*>(net_->net_type());
assert(use_type);
ivl_type_t prop_type = use_type->get_prop_type(pidx_);
return prop_type->base_type();
}
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid, NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid,
ivl_select_type_t sel_type) ivl_select_type_t sel_type)
: expr_(exp), base_(base), sel_type_(sel_type) : expr_(exp), base_(base), sel_type_(sel_type)

View File

@ -1,7 +1,7 @@
#ifndef __netlist_H #ifndef __netlist_H
#define __netlist_H #define __netlist_H
/* /*
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 1998-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -3945,6 +3945,8 @@ class NetEProperty : public NetExpr {
inline const NetNet* get_sig() const { return net_; } inline const NetNet* get_sig() const { return net_; }
inline size_t property_idx() const { return pidx_; } inline size_t property_idx() const { return pidx_; }
public: // Overridden methods
ivl_variable_type_t expr_type() const;
virtual void expr_scan(struct expr_scan_t*) const; virtual void expr_scan(struct expr_scan_t*) const;
virtual NetEProperty* dup_expr() const; virtual NetEProperty* dup_expr() const;
virtual NexusSet* nex_input(bool rem_out = true); virtual NexusSet* nex_input(bool rem_out = true);

34
netscalar.cc Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2013 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "netscalar.h"
using namespace std;
netreal_t netreal_t::type_real;
netreal_t netreal_t::type_shortreal;
netreal_t::~netreal_t()
{
}
ivl_variable_type_t netreal_t::base_type() const
{
return IVL_VT_REAL;
}

37
netscalar.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef __netscalar_H
#define __netscalar_H
/*
* Copyright (c) 2013 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
# include "nettypes.h"
class netreal_t : public ivl_type_s {
public:
inline explicit netreal_t() { }
~netreal_t();
ivl_variable_type_t base_type() const;
public:
static netreal_t type_real;
static netreal_t type_shortreal;
};
#endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -21,6 +21,8 @@
using namespace std; using namespace std;
netvector_t netvector_t::atom2s64 (IVL_VT_BOOL, 63, 0, true);
netvector_t netvector_t::atom2u64 (IVL_VT_BOOL, 63, 0, false);
netvector_t netvector_t::atom2s32 (IVL_VT_BOOL, 31, 0, true); netvector_t netvector_t::atom2s32 (IVL_VT_BOOL, 31, 0, true);
netvector_t netvector_t::atom2u32 (IVL_VT_BOOL, 31, 0, false); netvector_t netvector_t::atom2u32 (IVL_VT_BOOL, 31, 0, false);
netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 15, 0, true); netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 15, 0, true);

View File

@ -1,7 +1,7 @@
#ifndef __netvector_H #ifndef __netvector_H
#define __netvector_H #define __netvector_H
/* /*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -67,6 +67,8 @@ class netvector_t : public ivl_type_s {
public: public:
// Some commonly used predefined types // Some commonly used predefined types
static netvector_t atom2s64;
static netvector_t atom2u64;
static netvector_t atom2s32; static netvector_t atom2s32;
static netvector_t atom2u32; static netvector_t atom2u32;
static netvector_t atom2s16; static netvector_t atom2s16;

View File

@ -1,7 +1,7 @@
#ifndef __pform_types_H #ifndef __pform_types_H
#define __pform_types_H #define __pform_types_H
/* /*
* Copyright (c) 2007-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2007-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -174,6 +174,8 @@ struct real_type_t : public data_type_t {
enum type_t { REAL, SHORTREAL }; enum type_t { REAL, SHORTREAL };
inline explicit real_type_t(type_t tc) : type_code(tc) { } inline explicit real_type_t(type_t tc) : type_code(tc) { }
type_t type_code; type_t type_code;
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
}; };
struct string_type_t : public data_type_t { struct string_type_t : public data_type_t {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2007-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -211,8 +211,13 @@ static void show_property_expression(ivl_expr_t net, unsigned ind)
const char* pnam = ivl_expr_name(net); const char* pnam = ivl_expr_name(net);
char*signed_flag = ivl_expr_signed(net)? "signed" : "unsigned"; char*signed_flag = ivl_expr_signed(net)? "signed" : "unsigned";
if (ivl_expr_value(net) == IVL_VT_REAL) {
fprintf(out, "%*s<property base=%s, prop=%s, real>\n", ind, "",
ivl_signal_basename(sig), pnam);
} else {
fprintf(out, "%*s<property base=%s, prop=%s, width=%u, %s>\n", ind, "", fprintf(out, "%*s<property base=%s, prop=%s, width=%u, %s>\n", ind, "",
ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag); ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag);
}
if (ivl_signal_data_type(sig) != IVL_VT_CLASS) { if (ivl_signal_data_type(sig) != IVL_VT_CLASS) {
fprintf(out, "%*sERROR: Property signal must be IVL_VT_CLASS, got %s.\n", fprintf(out, "%*sERROR: Property signal must be IVL_VT_CLASS, got %s.\n",
ind+3, "", data_type_string(ivl_signal_data_type(sig))); ind+3, "", data_type_string(ivl_signal_data_type(sig)));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2003-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -165,6 +165,15 @@ static void draw_number_real(ivl_expr_t expr)
mant, vexp, (vexp&0x4000)? '-' : '+', mant, wid); mant, vexp, (vexp&0x4000)? '-' : '+', mant, wid);
} }
static void draw_property_real(ivl_expr_t expr)
{
ivl_signal_t sig = ivl_expr_signal(expr);
unsigned pidx = ivl_expr_property_idx(expr);
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
fprintf(vvp_out, " %%prop/r %u;\n", pidx);
}
static void draw_realnum_real(ivl_expr_t expr) static void draw_realnum_real(ivl_expr_t expr)
{ {
double value = ivl_expr_dvalue(expr); double value = ivl_expr_dvalue(expr);
@ -503,6 +512,10 @@ void draw_eval_real(ivl_expr_t expr)
draw_number_real(expr); draw_number_real(expr);
break; break;
case IVL_EX_PROPERTY:
draw_property_real(expr);
break;
case IVL_EX_REALNUM: case IVL_EX_REALNUM:
draw_realnum_real(expr); draw_realnum_real(expr);
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 Stephen Williams (steve@icarus.com) * Copyright (c) 2011,2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -846,7 +846,8 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
if (prop_idx >= 0) { if (prop_idx >= 0) {
ivl_type_t sig_type = ivl_signal_net_type(sig); ivl_type_t sig_type = ivl_signal_net_type(sig);
ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx); ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx);
assert(ivl_type_base(prop_type) == IVL_VT_BOOL);
if (ivl_type_base(prop_type) == IVL_VT_BOOL) {
assert(ivl_type_packed_dimensions(prop_type) == 1); assert(ivl_type_packed_dimensions(prop_type) == 1);
assert(ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0)); assert(ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0));
int wid = ivl_type_packed_msb(prop_type,0) - ivl_type_packed_lsb(prop_type,0) + 1; int wid = ivl_type_packed_msb(prop_type,0) - ivl_type_packed_lsb(prop_type,0) + 1;
@ -855,8 +856,23 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig); fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
fprintf(vvp_out, " %%store/prop/v %d, %u, %u;\n", prop_idx, val.base, val.wid); fprintf(vvp_out, " %%store/prop/v %d, %u, %u;\n", prop_idx, val.base, val.wid);
fprintf(vvp_out, " %%pop/obj 1;\n");
clr_vector(val); clr_vector(val);
} else if (ivl_type_base(prop_type) == IVL_VT_REAL) {
/* Calculate the real value into the real value
stack. The %store/prop/r will pop the stack
value. */
draw_eval_real(rval);
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
fprintf(vvp_out, " %%store/prop/r %d;\n", prop_idx);
fprintf(vvp_out, " %%pop/obj 1;\n");
} else {
assert(0);
}
} else { } else {
/* There is no property select, so evaluate the r-value /* There is no property select, so evaluate the r-value
as an object and assign the entire object to the as an object and assign the entire object to the

View File

@ -50,6 +50,9 @@ class class_property_t {
virtual void set_vec4(char*buf, const vvp_vector4_t&val); virtual void set_vec4(char*buf, const vvp_vector4_t&val);
virtual void get_vec4(char*buf, vvp_vector4_t&val); virtual void get_vec4(char*buf, vvp_vector4_t&val);
virtual void set_real(char*buf, double val);
virtual double get_real(char*buf);
protected: protected:
size_t offset_; size_t offset_;
}; };
@ -76,6 +79,17 @@ void class_property_t::get_vec4(char*, vvp_vector4_t&)
assert(0); assert(0);
} }
void class_property_t::set_real(char*, double)
{
assert(0);
}
double class_property_t::get_real(char*)
{
assert(0);
return 0.0;
}
/* /*
*/ */
template <class T> class property_atom : public class_property_t { template <class T> class property_atom : public class_property_t {
@ -91,15 +105,36 @@ template <class T> class property_atom : public class_property_t {
*tmp = 0; *tmp = 0;
} }
void set_vec4(char*buf, const vvp_vector4_t&val) void set_vec4(char*buf, const vvp_vector4_t&val);
{ void get_vec4(char*buf, vvp_vector4_t&val);
};
template <class T> class property_real : public class_property_t {
public:
inline explicit property_real(void) { }
~property_real() { }
size_t instance_size() const { return sizeof(T); }
public:
void construct(char*buf) const
{ T*tmp = reinterpret_cast<T*> (buf+offset_);
*tmp = 0.0;
}
void set_real(char*buf, double val);
double get_real(char*buf);
};
template <class T> void property_atom<T>::set_vec4(char*buf, const vvp_vector4_t&val)
{
T*tmp = reinterpret_cast<T*> (buf+offset_); T*tmp = reinterpret_cast<T*> (buf+offset_);
bool flag = vector4_to_value(val, *tmp, true, false); bool flag = vector4_to_value(val, *tmp, true, false);
assert(flag); assert(flag);
} }
void get_vec4(char*buf, vvp_vector4_t&val) template <class T> void property_atom<T>::get_vec4(char*buf, vvp_vector4_t&val)
{ {
T*src = reinterpret_cast<T*> (buf+offset_); T*src = reinterpret_cast<T*> (buf+offset_);
const size_t tmp_cnt = (sizeof(T) + sizeof(unsigned long)-1)/sizeof(unsigned long); const size_t tmp_cnt = (sizeof(T) + sizeof(unsigned long)-1)/sizeof(unsigned long);
unsigned long tmp[tmp_cnt]; unsigned long tmp[tmp_cnt];
@ -109,8 +144,19 @@ template <class T> class property_atom : public class_property_t {
val.resize(8*sizeof(T)); val.resize(8*sizeof(T));
val.setarray(0, val.size(), tmp); val.setarray(0, val.size(), tmp);
} }
};
template <class T> void property_real<T>::set_real(char*buf, double val)
{
T*tmp = reinterpret_cast<T*>(buf+offset_);
*tmp = val;
}
template <class T> double property_real<T>::get_real(char*buf)
{
T*tmp = reinterpret_cast<T*>(buf+offset_);
return *tmp;
}
/* **** */ /* **** */
@ -141,6 +187,8 @@ void class_type::set_property(size_t idx, const string&name, const string&type)
properties_[idx].type = new property_atom<int32_t>; properties_[idx].type = new property_atom<int32_t>;
else if (type == "sb64") else if (type == "sb64")
properties_[idx].type = new property_atom<int64_t>; properties_[idx].type = new property_atom<int64_t>;
else if (type == "r")
properties_[idx].type = new property_real<double>;
else else
properties_[idx].type = 0; properties_[idx].type = 0;
} }
@ -152,6 +200,7 @@ void class_type::finish_setup(void)
// figures out how much memory a complete instance will need. // figures out how much memory a complete instance will need.
size_t accum = 0; size_t accum = 0;
for (size_t idx = 0 ; idx < properties_.size() ; idx += 1) { for (size_t idx = 0 ; idx < properties_.size() ; idx += 1) {
assert(properties_[idx].type);
size_t instance_size = properties_[idx].type->instance_size(); size_t instance_size = properties_[idx].type->instance_size();
accum += instance_size; accum += instance_size;
size_map[instance_size].push_back(idx); size_map[instance_size].push_back(idx);
@ -211,6 +260,21 @@ void class_type::get_vec4(class_type::inst_t obj, size_t pid,
properties_[pid].type->get_vec4(buf, val); properties_[pid].type->get_vec4(buf, val);
} }
void class_type::set_real(class_type::inst_t obj, size_t pid,
double val) const
{
char*buf = reinterpret_cast<char*> (obj);
assert(pid < properties_.size());
properties_[pid].type->set_real(buf, val);
}
double class_type::get_real(class_type::inst_t obj, size_t pid) const
{
char*buf = reinterpret_cast<char*> (obj);
assert(pid < properties_.size());
return properties_[pid].type->get_real(buf);
}
int class_type::get_type_code(void) const int class_type::get_type_code(void) const
{ {
return vpiClassDefn; return vpiClassDefn;

View File

@ -1,7 +1,7 @@
#ifndef __class_type_H #ifndef __class_type_H
#define __class_type_H #define __class_type_H
/* /*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -61,6 +61,8 @@ class class_type : public __vpiHandle {
void set_vec4(inst_t inst, size_t pid, const vvp_vector4_t&val) const; void set_vec4(inst_t inst, size_t pid, const vvp_vector4_t&val) const;
void get_vec4(inst_t inst, size_t pid, vvp_vector4_t&val) const; void get_vec4(inst_t inst, size_t pid, vvp_vector4_t&val) const;
void set_real(inst_t inst, size_t pid, double val) const;
double get_real(inst_t inst, size_t pid) const;
public: // VPI related methods public: // VPI related methods
int get_type_code(void) const; int get_type_code(void) const;

View File

@ -1,7 +1,7 @@
#ifndef __codes_H #ifndef __codes_H
#define __codes_H #define __codes_H
/* /*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -159,11 +159,13 @@ extern bool of_NULL(vthread_t thr, vvp_code_t code);
extern bool of_OR(vthread_t thr, vvp_code_t code); extern bool of_OR(vthread_t thr, vvp_code_t code);
extern bool of_ORR(vthread_t thr, vvp_code_t code); extern bool of_ORR(vthread_t thr, vvp_code_t code);
extern bool of_PAD(vthread_t thr, vvp_code_t code); extern bool of_PAD(vthread_t thr, vvp_code_t code);
extern bool of_POP_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_POP_REAL(vthread_t thr, vvp_code_t code); extern bool of_POP_REAL(vthread_t thr, vvp_code_t code);
extern bool of_POP_STR(vthread_t thr, vvp_code_t code); extern bool of_POP_STR(vthread_t thr, vvp_code_t code);
extern bool of_POW(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_S(vthread_t thr, vvp_code_t code);
extern bool of_POW_WR(vthread_t thr, vvp_code_t code); extern bool of_POW_WR(vthread_t thr, vvp_code_t code);
extern bool of_PROP_R(vthread_t thr, vvp_code_t code);
extern bool of_PROP_V(vthread_t thr, vvp_code_t code); extern bool of_PROP_V(vthread_t thr, vvp_code_t code);
extern bool of_PUSHI_STR(vthread_t thr, vvp_code_t code); extern bool of_PUSHI_STR(vthread_t thr, vvp_code_t code);
extern bool of_PUSHI_REAL(vthread_t thr, vvp_code_t code); extern bool of_PUSHI_REAL(vthread_t thr, vvp_code_t code);
@ -183,6 +185,7 @@ extern bool of_SHIFTR_S_I0(vthread_t thr, vvp_code_t code);
extern bool of_STORE_DAR_R(vthread_t thr, vvp_code_t code); extern bool of_STORE_DAR_R(vthread_t thr, vvp_code_t code);
extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code); extern bool of_STORE_DAR_STR(vthread_t thr, vvp_code_t code);
extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code); extern bool of_STORE_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_STORE_PROP_R(vthread_t thr, vvp_code_t code);
extern bool of_STORE_PROP_V(vthread_t thr, vvp_code_t code); extern bool of_STORE_PROP_V(vthread_t thr, vvp_code_t code);
extern bool of_STORE_REAL(vthread_t thr, vvp_code_t code); extern bool of_STORE_REAL(vthread_t thr, vvp_code_t code);
extern bool of_STORE_REALA(vthread_t thr, vvp_code_t code); extern bool of_STORE_REALA(vthread_t thr, vvp_code_t code);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -207,11 +207,13 @@ static const struct opcode_table_s opcode_table[] = {
{ "%or", of_OR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%or", of_OR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%or/r", of_ORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%or/r", of_ORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pad", of_PAD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%pad", of_PAD, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pop/obj", of_POP_OBJ, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%pop/real",of_POP_REAL,1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%pop/real",of_POP_REAL,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%pop/str", of_POP_STR, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%pop/str", of_POP_STR, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%pow", of_POW, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%pow/s", of_POW_S, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pow/wr", of_POW_WR, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%pow/wr", of_POW_WR, 0, {OA_NONE, OA_NONE, OA_NONE} },
{ "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%prop/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%prop/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%pushi/real",of_PUSHI_REAL,2,{OA_BIT1, OA_BIT2, OA_NONE} }, { "%pushi/real",of_PUSHI_REAL,2,{OA_BIT1, OA_BIT2, OA_NONE} },
{ "%pushi/str", of_PUSHI_STR, 1,{OA_STRING, OA_NONE, OA_NONE} }, { "%pushi/str", of_PUSHI_STR, 1,{OA_STRING, OA_NONE, OA_NONE} },
@ -230,6 +232,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/dar/r", of_STORE_DAR_R, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%store/dar/str",of_STORE_DAR_STR, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
{ "%store/obj", of_STORE_OBJ, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} }, { "%store/obj", of_STORE_OBJ, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%store/prop/r",of_STORE_PROP_R,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/prop/v",of_STORE_PROP_V,3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%store/prop/v",of_STORE_PROP_V,3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%store/real", of_STORE_REAL, 1, {OA_FUNC_PTR,OA_NONE, 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/reala", of_STORE_REALA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
* *
*/ */
@ -865,11 +865,13 @@ or sign extending a vector.
* %pop/str <num> * %pop/str <num>
* %pop/real <num> * %pop/real <num>
* %pop/obj <num>
Pop this many items from the string stack. This is the opposite of the Pop this many items from the string/real/object stack. This is the
%pushX/str opcode which pushes a string to the stack. The %pop/str is opposite of the %pushX/str opcode which pushes a string to the
not normally needed because the %store/str includes an implicit pop, stack. The %pop/str is not normally needed because the %store/str
but sometimes it is necessary to pop explicitly. includes an implicit pop, but sometimes it is necessary to pop
explicitly.
* %pow <bit-l>, <bit-r>, <wid> * %pow <bit-l>, <bit-r>, <wid>
* %pow/s <bit-l>, <bit-r>, <wid> * %pow/s <bit-l>, <bit-r>, <wid>
@ -887,9 +889,12 @@ This opcode raises the left operand by the right operand, and pushes
the result. the result.
* %prop/v <pid>, <base>, <wid> * %prop/v <pid>, <base>, <wid>
* %prop/r <pid>
Write the vector into property number <pid> of the class object on the Write the vector (/v) or real value (/r) into property number <pid> of
top of the object stack. The stack is NOT popped. the class object on the top of the object stack. The real value is popped.
The class object stack is NOT popped.
* %pushi/real <mant>, <exp> * %pushi/real <mant>, <exp>
@ -1009,6 +1014,13 @@ variable given by the label.
See also %load/obj. See also %load/obj.
* %store/prop/r <index>
* %store/prop/v <index>, <bit>, <wid>
The %store/prop/r pops a real value from the real stack and stores it
into the the property number <index> of a cobject in the top of the
object stack. The cobject is NOT popped.
* %store/real <var-label> * %store/real <var-label>
* %store/reala <var-label>, <index> * %store/reala <var-label>, <index>

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -182,6 +182,13 @@ struct vthread_s {
obj = stack_obj_[stack_obj_size_]; obj = stack_obj_[stack_obj_size_];
stack_obj_[stack_obj_size_].reset(0); stack_obj_[stack_obj_size_].reset(0);
} }
inline void pop_object(unsigned cnt)
{
assert(cnt <= stack_obj_size_);
for (size_t idx = stack_obj_size_-cnt ; idx < stack_obj_size_ ; idx += 1)
stack_obj_[idx].reset(0);
stack_obj_size_ -= cnt;
}
inline void push_object(const vvp_object_t&obj) inline void push_object(const vvp_object_t&obj)
{ {
assert(stack_obj_size_ < STACK_OBJ_MAX_SIZE); assert(stack_obj_size_ < STACK_OBJ_MAX_SIZE);
@ -4414,6 +4421,16 @@ bool of_NOR(vthread_t thr, vvp_code_t cp)
return cp->opcode(thr, cp); return cp->opcode(thr, cp);
} }
/*
* %pop/obj <number>
*/
bool of_POP_OBJ(vthread_t thr, vvp_code_t cp)
{
unsigned cnt = cp->number;
thr->pop_object(cnt);
return true;
}
/* /*
* %pop/real <number> * %pop/real <number>
*/ */
@ -4516,6 +4533,25 @@ bool of_POW_WR(vthread_t thr, vvp_code_t)
return true; return true;
} }
/*
* %prop/r <pid>
*
* Load a real value from the cobject and push it onto the real value
* stack.
*/
bool of_PROP_R(vthread_t thr, vvp_code_t cp)
{
unsigned pid = cp->number;
vvp_object_t&obj = thr->peek_object();
vvp_cobject*cobj = obj.peek<vvp_cobject>();
double val = cobj->get_real(pid);
thr->push_real(val);
return true;
}
/* /*
* %prop/v <pid> <base> <wid> * %prop/v <pid> <base> <wid>
* *
@ -5057,6 +5093,27 @@ bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp)
return true; return true;
} }
/*
* %store/prop/r <id>
*
* Pop a real value from the real stack, and store the value into the
* property of the object references by the top of the stack. Do NOT
* pop the object stack.
*/
bool of_STORE_PROP_R(vthread_t thr, vvp_code_t cp)
{
size_t pid = cp->number;
double val = thr->pop_real();
vvp_object_t&obj = thr->peek_object();
vvp_cobject*cobj = obj.peek<vvp_cobject>();
assert(cobj);
cobj->set_real(pid, val);
return true;
}
/* /*
* %store/prop/v <id> <base> <wid> * %store/prop/v <id> <base> <wid>
* *

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -44,3 +44,13 @@ void vvp_cobject::get_vec4(size_t pid, vvp_vector4_t&val)
{ {
defn_->get_vec4(properties_, pid, val); defn_->get_vec4(properties_, pid, val);
} }
void vvp_cobject::set_real(size_t pid, double val)
{
defn_->set_real(properties_, pid, val);
}
double vvp_cobject::get_real(size_t pid)
{
return defn_->get_real(properties_, pid);
}

View File

@ -1,7 +1,7 @@
#ifndef __vvp_cobject_H #ifndef __vvp_cobject_H
#define __vvp_cobject_H #define __vvp_cobject_H
/* /*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com) * Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -34,6 +34,9 @@ class vvp_cobject : public vvp_object {
void set_vec4(size_t pid, const vvp_vector4_t&val); void set_vec4(size_t pid, const vvp_vector4_t&val);
void get_vec4(size_t pid, vvp_vector4_t&val); void get_vec4(size_t pid, vvp_vector4_t&val);
void set_real(size_t pid, double val);
double get_real(size_t pid);
private: private:
const class_type* defn_; const class_type* defn_;
// For now, only support 32bit bool signed properties. // For now, only support 32bit bool signed properties.