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 \
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.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_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 \

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
* and/or modify it in source code form under the terms of the GNU
@ -19,6 +19,7 @@
# include "pform_types.h"
# include "netlist.h"
# include "netscalar.h"
# include "netvector.h"
# include <typeinfo>
# 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
{
switch (type_code) {
case 64:
if (signed_flag)
return &netvector_t::atom2s64;
else
return &netvector_t::atom2u64;
case 32:
if (signed_flag)
return &netvector_t::atom2s32;
@ -62,3 +69,14 @@ ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
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
* 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,
ivl_select_type_t sel_type)
: expr_(exp), base_(base), sel_type_(sel_type)

View File

@ -1,7 +1,7 @@
#ifndef __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
* 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 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 NetEProperty* dup_expr() const;
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
* and/or modify it in source code form under the terms of the GNU
@ -21,6 +21,8 @@
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::atom2u32 (IVL_VT_BOOL, 31, 0, false);
netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 15, 0, true);

View File

@ -1,7 +1,7 @@
#ifndef __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
* 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:
// Some commonly used predefined types
static netvector_t atom2s64;
static netvector_t atom2u64;
static netvector_t atom2s32;
static netvector_t atom2u32;
static netvector_t atom2s16;

View File

@ -1,7 +1,7 @@
#ifndef __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
* 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 };
inline explicit real_type_t(type_t tc) : type_code(tc) { }
type_t type_code;
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
};
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
* 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);
char*signed_flag = ivl_expr_signed(net)? "signed" : "unsigned";
fprintf(out, "%*s<property base=%s, prop=%s, width=%u, %s>\n", ind, "",
ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag);
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, "",
ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag);
}
if (ivl_signal_data_type(sig) != IVL_VT_CLASS) {
fprintf(out, "%*sERROR: Property signal must be IVL_VT_CLASS, got %s.\n",
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
* 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);
}
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)
{
double value = ivl_expr_dvalue(expr);
@ -503,6 +512,10 @@ void draw_eval_real(ivl_expr_t expr)
draw_number_real(expr);
break;
case IVL_EX_PROPERTY:
draw_property_real(expr);
break;
case IVL_EX_REALNUM:
draw_realnum_real(expr);
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
* and/or modify it in source code form under the terms of the GNU
@ -846,16 +846,32 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
if (prop_idx >= 0) {
ivl_type_t sig_type = ivl_signal_net_type(sig);
ivl_type_t prop_type = ivl_type_prop_type(sig_type, prop_idx);
assert(ivl_type_base(prop_type) == IVL_VT_BOOL);
assert(ivl_type_packed_dimensions(prop_type) == 1);
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;
struct vector_info val = draw_eval_expr_wid(rval, wid, STUFF_OK_XZ);
if (ivl_type_base(prop_type) == IVL_VT_BOOL) {
assert(ivl_type_packed_dimensions(prop_type) == 1);
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;
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);
clr_vector(val);
struct vector_info val = draw_eval_expr_wid(rval, wid, STUFF_OK_XZ);
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, " %%pop/obj 1;\n");
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 {
/* There is no property select, so evaluate the r-value

View File

@ -50,6 +50,9 @@ class class_property_t {
virtual void set_vec4(char*buf, const 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:
size_t offset_;
};
@ -76,6 +79,17 @@ void class_property_t::get_vec4(char*, vvp_vector4_t&)
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 {
@ -91,27 +105,59 @@ template <class T> class property_atom : public class_property_t {
*tmp = 0;
}
void set_vec4(char*buf, const vvp_vector4_t&val)
{
T*tmp = reinterpret_cast<T*> (buf+offset_);
bool flag = vector4_to_value(val, *tmp, true, false);
assert(flag);
}
void get_vec4(char*buf, vvp_vector4_t&val)
{
T*src = reinterpret_cast<T*> (buf+offset_);
const size_t tmp_cnt = (sizeof(T) + sizeof(unsigned long)-1)/sizeof(unsigned long);
unsigned long tmp[tmp_cnt];
tmp[0] = src[0];
for (size_t idx = 1 ; idx < tmp_cnt ; idx += 1)
tmp[idx] = 0;
val.resize(8*sizeof(T));
val.setarray(0, val.size(), tmp);
}
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_);
bool flag = vector4_to_value(val, *tmp, true, false);
assert(flag);
}
template <class T> void property_atom<T>::get_vec4(char*buf, vvp_vector4_t&val)
{
T*src = reinterpret_cast<T*> (buf+offset_);
const size_t tmp_cnt = (sizeof(T) + sizeof(unsigned long)-1)/sizeof(unsigned long);
unsigned long tmp[tmp_cnt];
tmp[0] = src[0];
for (size_t idx = 1 ; idx < tmp_cnt ; idx += 1)
tmp[idx] = 0;
val.resize(8*sizeof(T));
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;
}
/* **** */
class_type::class_type(const string&nam, size_t nprop)
@ -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>;
else if (type == "sb64")
properties_[idx].type = new property_atom<int64_t>;
else if (type == "r")
properties_[idx].type = new property_real<double>;
else
properties_[idx].type = 0;
}
@ -152,6 +200,7 @@ void class_type::finish_setup(void)
// figures out how much memory a complete instance will need.
size_t accum = 0;
for (size_t idx = 0 ; idx < properties_.size() ; idx += 1) {
assert(properties_[idx].type);
size_t instance_size = properties_[idx].type->instance_size();
accum += instance_size;
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);
}
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
{
return vpiClassDefn;

View File

@ -1,7 +1,7 @@
#ifndef __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
* 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 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
int get_type_code(void) const;

View File

@ -1,7 +1,7 @@
#ifndef __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
* 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_ORR(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_STR(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_PROP_R(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_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_STR(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_REAL(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
* 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/r", of_ORR, 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/str", of_POP_STR, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%pow", of_POW, 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} },
{ "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%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/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/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/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/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} },

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/real <num>
* %pop/obj <num>
Pop this many items from the string stack. This is the opposite of the
%pushX/str opcode which pushes a string to the stack. The %pop/str is
not normally needed because the %store/str includes an implicit pop,
but sometimes it is necessary to pop explicitly.
Pop this many items from the string/real/object stack. This is the
opposite of the %pushX/str opcode which pushes a string to the
stack. The %pop/str is not normally needed because the %store/str
includes an implicit pop, but sometimes it is necessary to pop
explicitly.
* %pow <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.
* %prop/v <pid>, <base>, <wid>
* %prop/r <pid>
Write the vector into property number <pid> of the class object on the
top of the object stack. The stack is NOT popped.
Write the vector (/v) or real value (/r) into property number <pid> of
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>
@ -1009,6 +1014,13 @@ variable given by the label.
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/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
* 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_];
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)
{
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);
}
/*
* %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>
*/
@ -4516,6 +4533,25 @@ bool of_POW_WR(vthread_t thr, vvp_code_t)
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>
*
@ -5057,6 +5093,27 @@ bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp)
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>
*

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
* 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);
}
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
#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
* 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 get_vec4(size_t pid, vvp_vector4_t&val);
void set_real(size_t pid, double val);
double get_real(size_t pid);
private:
const class_type* defn_;
// For now, only support 32bit bool signed properties.