diff --git a/Makefile.in b/Makefile.in index d231f2669..78f50a4f3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 \ diff --git a/elab_type.cc b/elab_type.cc index 06938b66f..319603fae 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -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 # 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; +} diff --git a/net_expr.cc b/net_expr.cc index 83fd81192..0e3cb24f0 100644 --- a/net_expr.cc +++ b/net_expr.cc @@ -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(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) diff --git a/netlist.h b/netlist.h index 9e1bf3d31..7f502f5a3 100644 --- a/netlist.h +++ b/netlist.h @@ -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); diff --git a/netscalar.cc b/netscalar.cc new file mode 100644 index 000000000..0c0873da8 --- /dev/null +++ b/netscalar.cc @@ -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; +} diff --git a/netscalar.h b/netscalar.h new file mode 100644 index 000000000..b3aeec137 --- /dev/null +++ b/netscalar.h @@ -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 diff --git a/netvector.cc b/netvector.cc index cb602d9a7..143b271b9 100644 --- a/netvector.cc +++ b/netvector.cc @@ -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); diff --git a/netvector.h b/netvector.h index 3add278fb..2f46a0185 100644 --- a/netvector.h +++ b/netvector.h @@ -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; diff --git a/pform_types.h b/pform_types.h index 8af2d3c6e..10a80e188 100644 --- a/pform_types.h +++ b/pform_types.h @@ -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 { diff --git a/tgt-stub/expression.c b/tgt-stub/expression.c index e7a22cda4..5d5eebfcc 100644 --- a/tgt-stub/expression.c +++ b/tgt-stub/expression.c @@ -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\n", ind, "", - ivl_signal_basename(sig), pnam, ivl_expr_width(net), signed_flag); + if (ivl_expr_value(net) == IVL_VT_REAL) { + fprintf(out, "%*s\n", ind, "", + ivl_signal_basename(sig), pnam); + } else { + fprintf(out, "%*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))); diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 77dedf262..b4a9073d3 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -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; diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index f2eb92c37..04c1f5d25 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -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 diff --git a/vvp/class_type.cc b/vvp/class_type.cc index e061fdd6a..12336d349 100644 --- a/vvp/class_type.cc +++ b/vvp/class_type.cc @@ -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 property_atom : public class_property_t { @@ -91,27 +105,59 @@ template class property_atom : public class_property_t { *tmp = 0; } - void set_vec4(char*buf, const vvp_vector4_t&val) - { - T*tmp = reinterpret_cast (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 (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 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 (buf+offset_); + *tmp = 0.0; + } + + void set_real(char*buf, double val); + double get_real(char*buf); +}; + +template void property_atom::set_vec4(char*buf, const vvp_vector4_t&val) +{ + T*tmp = reinterpret_cast (buf+offset_); + bool flag = vector4_to_value(val, *tmp, true, false); + assert(flag); +} + +template void property_atom::get_vec4(char*buf, vvp_vector4_t&val) +{ + T*src = reinterpret_cast (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 void property_real::set_real(char*buf, double val) +{ + T*tmp = reinterpret_cast(buf+offset_); + *tmp = val; +} + +template double property_real::get_real(char*buf) +{ + T*tmp = reinterpret_cast(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; else if (type == "sb64") properties_[idx].type = new property_atom; + else if (type == "r") + properties_[idx].type = new property_real; 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 (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 (obj); + assert(pid < properties_.size()); + return properties_[pid].type->get_real(buf); +} + int class_type::get_type_code(void) const { return vpiClassDefn; diff --git a/vvp/class_type.h b/vvp/class_type.h index f7a5564d1..d435d91c9 100644 --- a/vvp/class_type.h +++ b/vvp/class_type.h @@ -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; diff --git a/vvp/codes.h b/vvp/codes.h index 723d7a210..c50b51ed2 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -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); diff --git a/vvp/compile.cc b/vvp/compile.cc index 119812a94..e71b3ce95 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -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} }, diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index b1348398a..27daabbf0 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -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 * %pop/real +* %pop/obj -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 , , * %pow/s , , @@ -887,9 +889,12 @@ This opcode raises the left operand by the right operand, and pushes the result. * %prop/v , , +* %prop/r -Write the vector into property number 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 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 , @@ -1009,6 +1014,13 @@ variable given by the label. See also %load/obj. +* %store/prop/r +* %store/prop/v , , + +The %store/prop/r pops a real value from the real stack and stores it +into the the property number of a cobject in the top of the +object stack. The cobject is NOT popped. + * %store/real * %store/reala , diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 5b32cc17b..f36123a25 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -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 + */ +bool of_POP_OBJ(vthread_t thr, vvp_code_t cp) +{ + unsigned cnt = cp->number; + thr->pop_object(cnt); + return true; +} + /* * %pop/real */ @@ -4516,6 +4533,25 @@ bool of_POW_WR(vthread_t thr, vvp_code_t) return true; } +/* + * %prop/r + * + * 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(); + + double val = cobj->get_real(pid); + thr->push_real(val); + + return true; +} + /* * %prop/v * @@ -5057,6 +5093,27 @@ bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp) return true; } +/* + * %store/prop/r + * + * 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(); + assert(cobj); + + cobj->set_real(pid, val); + + return true; +} + /* * %store/prop/v * diff --git a/vvp/vvp_cobject.cc b/vvp/vvp_cobject.cc index b2d85e822..212d42f5c 100644 --- a/vvp/vvp_cobject.cc +++ b/vvp/vvp_cobject.cc @@ -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); +} diff --git a/vvp/vvp_cobject.h b/vvp/vvp_cobject.h index 2cb9b7b00..b463eca22 100644 --- a/vvp/vvp_cobject.h +++ b/vvp/vvp_cobject.h @@ -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.