Merge branch 'x-mil6'
This commit is contained in:
commit
ee58fd749c
|
|
@ -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 \
|
||||
|
|
|
|||
2
PExpr.h
2
PExpr.h
|
|
@ -518,6 +518,8 @@ class PENumber : public PExpr {
|
|||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid, unsigned) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
|
|
|
|||
105
elab_expr.cc
105
elab_expr.cc
|
|
@ -144,6 +144,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, ivl_type_t, unsigned) cons
|
|||
<< " elaborate (ivl_type_t) this expression. " << endl;
|
||||
cerr << get_fileline() << ": : Expression is: " << *this
|
||||
<< endl;
|
||||
cerr << get_fileline() << ": : Expression type: " << typeid(*this).name() << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1091,11 +1092,13 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
|||
if (path_.size() < 2)
|
||||
return 0;
|
||||
|
||||
perm_string member_name;
|
||||
ivl_type_t member_type = 0;
|
||||
pform_name_t use_path = path_;
|
||||
perm_string method_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
|
||||
NetNet *net;
|
||||
NetNet *net = 0;
|
||||
const NetExpr *par;
|
||||
NetEvent *eve;
|
||||
const NetExpr *ex1, *ex2;
|
||||
|
|
@ -1103,13 +1106,54 @@ unsigned PECallFunction::test_width_method_(Design*des, NetScope*scope,
|
|||
symbol_search(this, des, scope, use_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
|
||||
const netdarray_t*use_darray = 0;
|
||||
|
||||
if (net != 0)
|
||||
use_darray = net->darray_type();
|
||||
|
||||
// Net is not found, but maybe it is a member of a
|
||||
// struct or class. Try to locate net without the member
|
||||
// name and test if it is a type that has members.
|
||||
if (net == 0 && use_path.size() >= 2) {
|
||||
pform_name_t tmp_path = use_path;
|
||||
member_name = peek_tail_name(tmp_path);
|
||||
tmp_path.pop_back();
|
||||
|
||||
net = 0;
|
||||
symbol_search(this, des, scope, tmp_path,
|
||||
net, par, eve, ex1, ex2);
|
||||
if (net && net->class_type()) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
|
||||
<< "Found net=" << tmp_path
|
||||
<< ", member_name=" << member_name
|
||||
<< ", method_name=" << method_name
|
||||
<< endl;
|
||||
}
|
||||
|
||||
netclass_t* class_type = net->class_type();
|
||||
member_type = class_type->get_property(member_name);
|
||||
use_path = tmp_path;
|
||||
|
||||
use_darray = dynamic_cast<const netdarray_t*> (member_type);
|
||||
|
||||
} else {
|
||||
member_name = perm_string();
|
||||
net = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// After all, no sign of a net match. Give up.
|
||||
if (net == 0)
|
||||
return 0;
|
||||
|
||||
netdarray_t*darray = net->darray_type();
|
||||
|
||||
// function int size()
|
||||
if (darray && method_name == "size") {
|
||||
if (use_darray && method_name == "size") {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::test_width_method_: "
|
||||
<< "Match darray size() method." << endl;
|
||||
}
|
||||
|
||||
expr_type_ = IVL_VT_BOOL;
|
||||
expr_width_ = 32;
|
||||
min_width_ = expr_width_;
|
||||
|
|
@ -1866,7 +1910,7 @@ NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
|||
perm_string method_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
|
||||
NetNet *net;
|
||||
NetNet *net = 0;
|
||||
const NetExpr *par;
|
||||
NetEvent *eve;
|
||||
const NetExpr *ex1, *ex2;
|
||||
|
|
@ -2570,9 +2614,37 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
net, par, eve,
|
||||
ex1, ex2);
|
||||
|
||||
if (net == 0 && gn_system_verilog() && path_.size() >= 2) {
|
||||
pform_name_t use_path = path_;
|
||||
name_component_t member_comp = use_path.back();
|
||||
use_path.pop_back();
|
||||
|
||||
ivl_assert(*this, net == 0);
|
||||
symbol_search(this, des, scope, use_path, net, par, eve, ex1, ex2);
|
||||
|
||||
if (net == 0) {
|
||||
// Nope, no struct/class with member.
|
||||
|
||||
} else if (net->struct_type() != 0) {
|
||||
return check_for_struct_members(this, des, scope,
|
||||
net, use_path.back().index,
|
||||
member_comp);
|
||||
|
||||
} else if (net->class_type()!=0) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_expr: "
|
||||
<< "Ident " << use_path
|
||||
<< " look for property " << member_comp << endl;
|
||||
}
|
||||
|
||||
return check_for_class_property(this, des, scope,
|
||||
net, member_comp);
|
||||
}
|
||||
}
|
||||
|
||||
if (net == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Expecting idents wtih ntype to be signals." << endl;
|
||||
<< "Expecting idents with ntype to be signals." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4192,6 +4264,27 @@ unsigned PENumber::test_width(Design*, NetScope*, width_mode_t&mode)
|
|||
return expr_width_;
|
||||
}
|
||||
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, ivl_type_t ntype, unsigned) const
|
||||
{
|
||||
const netvector_t*use_type = dynamic_cast<const netvector_t*> (ntype);
|
||||
if (use_type == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "I don't know how cast numbers to this type."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum use_val = value();
|
||||
use_val .has_sign( use_type->get_signed() );
|
||||
use_val = cast_to_width(use_val, use_type->packed_width());
|
||||
|
||||
NetEConst*tmp = new NetEConst(use_val);
|
||||
tmp->set_line(*this);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConst* PENumber::elaborate_expr(Design*, NetScope*,
|
||||
unsigned expr_wid, unsigned) const
|
||||
{
|
||||
|
|
|
|||
15
elab_lval.cc
15
elab_lval.cc
|
|
@ -25,6 +25,7 @@
|
|||
# include "netmisc.h"
|
||||
# include "netstruct.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "compiler.h"
|
||||
# include <cstdlib>
|
||||
# include <iostream>
|
||||
|
|
@ -716,7 +717,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
|
||||
bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope,
|
||||
NetAssign_*lv,
|
||||
const perm_string&method_name) const
|
||||
{
|
||||
|
|
@ -740,6 +741,18 @@ bool PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*,
|
|||
}
|
||||
|
||||
lv->set_property(method_name);
|
||||
|
||||
const netdarray_t*mtype = dynamic_cast<const netdarray_t*> (ptype);
|
||||
if (mtype) {
|
||||
const name_component_t&name_tail = path_.back();
|
||||
if (name_tail.index.size() > 0) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "Array index of array properties not supported."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -865,7 +865,7 @@ static bool evaluate_ranges(Design*des, NetScope*scope,
|
|||
return bad_msb | bad_lsb;
|
||||
}
|
||||
|
||||
static netclass_t* locate_class_type(Design*des, NetScope*scope,
|
||||
static netclass_t* locate_class_type(Design*, NetScope*scope,
|
||||
class_type_t*class_type)
|
||||
{
|
||||
netclass_t*use_class = scope->find_class(class_type->name);
|
||||
|
|
@ -928,7 +928,7 @@ static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
|
|||
{
|
||||
|
||||
vector<netrange_t>packed_dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->packed_dims);
|
||||
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->dims);
|
||||
ivl_assert(*data_type, !bad_range);
|
||||
|
||||
ivl_type_s*element_type = elaborate_type(des, scope, data_type->base_type);
|
||||
|
|
|
|||
44
elab_type.cc
44
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,9 @@
|
|||
|
||||
# include "pform_types.h"
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netscalar.h"
|
||||
# include "netvector.h"
|
||||
# include <typeinfo>
|
||||
# include "ivl_assert.h"
|
||||
|
|
@ -37,6 +40,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 +71,36 @@ ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ivl_type_s* class_type_t::elaborate_type(Design*des, NetScope*scope) const
|
||||
{
|
||||
return scope->find_class(name);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ivl_type_s* string_type_t::elaborate_type(Design*, NetScope*) const
|
||||
{
|
||||
return &netstring_t::type_string;
|
||||
}
|
||||
|
||||
ivl_type_s* uarray_type_t::elaborate_type(Design*des, NetScope*scope) const
|
||||
{
|
||||
|
||||
ivl_type_t btype = base_type->elaborate_type(des, scope);
|
||||
|
||||
assert(dims->size() == 1);
|
||||
list<pform_range_t>::const_iterator cur = dims->begin();
|
||||
assert(cur->first == 0 && cur->second==0);
|
||||
ivl_type_s*res = new netdarray_t(btype);
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
24
elaborate.cc
24
elaborate.cc
|
|
@ -2381,6 +2381,14 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
NetExpr*rv;
|
||||
const ivl_type_s*lv_net_type = lv->net_type();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PAssign::elaborate: ";
|
||||
if (lv_net_type)
|
||||
cerr << "lv_net_type=" << *lv_net_type << endl;
|
||||
else
|
||||
cerr << "lv_net_type=<nil>" << endl;
|
||||
}
|
||||
|
||||
/* If the l-value is a compound type of some sort, then use
|
||||
the newer net_type form of the elaborate_rval_ method to
|
||||
handle the new types. */
|
||||
|
|
@ -2388,9 +2396,21 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
ivl_assert(*this, lv->more==0);
|
||||
rv = elaborate_rval_(des, scope, lv_net_type);
|
||||
|
||||
} else if (dynamic_cast<const netdarray_t*> (lv_net_type)) {
|
||||
} else if (const netdarray_t*dtype = dynamic_cast<const netdarray_t*> (lv_net_type)) {
|
||||
ivl_assert(*this, lv->more==0);
|
||||
rv = elaborate_rval_(des, scope, lv_net_type);
|
||||
if (debug_elaborate) {
|
||||
if (lv->word())
|
||||
cerr << get_fileline() << ": PAssign::elaborate: "
|
||||
<< "lv->word() = " << *lv->word() << endl;
|
||||
else
|
||||
cerr << get_fileline() << ": PAssign::elaborate: "
|
||||
<< "lv->word() = <nil>" << endl;
|
||||
}
|
||||
ivl_type_t use_lv_type = lv_net_type;
|
||||
if (lv->word())
|
||||
use_lv_type = dtype->element_type();
|
||||
|
||||
rv = elaborate_rval_(des, scope, use_lv_type);
|
||||
|
||||
} else {
|
||||
/* Elaborate the r-value expression, then try to evaluate it. */
|
||||
|
|
|
|||
1
ivl.def
1
ivl.def
|
|
@ -313,6 +313,7 @@ ivl_type_packed_msb
|
|||
ivl_type_prop_name
|
||||
ivl_type_prop_type
|
||||
ivl_type_properties
|
||||
ivl_type_signed
|
||||
|
||||
ivl_udp_init
|
||||
ivl_udp_file
|
||||
|
|
|
|||
|
|
@ -2232,6 +2232,10 @@ extern unsigned ivl_switch_lineno(ivl_switch_t net);
|
|||
* Return the type of the element of an array. This is only valid
|
||||
* for array types.
|
||||
*
|
||||
* ivl_type_signed
|
||||
* Return TRUE if the type represents a signed packed vector or
|
||||
* signed atomic type, and FALSE otherwise.
|
||||
*
|
||||
* SEMANTIC NOTES
|
||||
*
|
||||
* Class types have names and properties.
|
||||
|
|
@ -2241,6 +2245,7 @@ extern ivl_type_t ivl_type_element(ivl_type_t net);
|
|||
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
||||
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
||||
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
||||
extern int ivl_type_signed(ivl_type_t net);
|
||||
extern const char* ivl_type_name(ivl_type_t net);
|
||||
extern int ivl_type_properties(ivl_type_t net);
|
||||
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
||||
|
|
|
|||
12
net_expr.cc
12
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
|
||||
|
|
@ -357,12 +357,22 @@ NetEProperty::NetEProperty(NetNet*net, perm_string pnam)
|
|||
pidx_ = use_type->property_idx_from_name(pnam);
|
||||
ivl_type_t prop_type = use_type->get_prop_type(pidx_);
|
||||
expr_width(prop_type->packed_width());
|
||||
cast_signed(prop_type->get_signed());
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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;
|
||||
netstring_t netstring_t::type_string;
|
||||
|
||||
netreal_t::~netreal_t()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_variable_type_t netreal_t::base_type() const
|
||||
{
|
||||
return IVL_VT_REAL;
|
||||
}
|
||||
|
||||
netstring_t::~netstring_t()
|
||||
{
|
||||
}
|
||||
|
||||
ivl_variable_type_t netstring_t::base_type() const
|
||||
{
|
||||
return IVL_VT_STRING;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#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;
|
||||
};
|
||||
|
||||
class netstring_t : public ivl_type_s {
|
||||
|
||||
public:
|
||||
inline explicit netstring_t() { }
|
||||
~netstring_t();
|
||||
|
||||
ivl_variable_type_t base_type() const;
|
||||
|
||||
public:
|
||||
static netstring_t type_string;
|
||||
};
|
||||
|
||||
#endif
|
||||
12
netvector.cc
12
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,12 +21,14 @@
|
|||
|
||||
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, 16, 0, true);
|
||||
netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 16, 0, false);
|
||||
netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 8, 0, true);
|
||||
netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 8, 0, false);
|
||||
netvector_t netvector_t::atom2s16 (IVL_VT_BOOL, 15, 0, true);
|
||||
netvector_t netvector_t::atom2u16 (IVL_VT_BOOL, 15, 0, false);
|
||||
netvector_t netvector_t::atom2s8 (IVL_VT_BOOL, 7, 0, true);
|
||||
netvector_t netvector_t::atom2u8 (IVL_VT_BOOL, 7, 0, false);
|
||||
|
||||
netvector_t::netvector_t(ivl_variable_type_t type, long msb, long lsb, bool flag)
|
||||
: type_(type), signed_(flag), isint_(false), is_scalar_(false)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,13 @@ void parray_type_t::pform_dump(ostream&out, unsigned indent) const
|
|||
base_type->pform_dump(out, indent+4);
|
||||
}
|
||||
|
||||
void uarray_type_t::pform_dump(ostream&out, unsigned indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Unpacked array " << "[...]"
|
||||
<< " of:" << endl;
|
||||
base_type->pform_dump(out, indent+4);
|
||||
}
|
||||
|
||||
void struct_type_t::pform_dump(ostream&out, unsigned indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked")
|
||||
|
|
|
|||
|
|
@ -57,7 +57,18 @@ void pform_class_property(const struct vlltype&loc,
|
|||
; cur != decls->end() ; ++cur) {
|
||||
|
||||
decl_assignment_t*curp = *cur;
|
||||
pform_cur_class->type->properties[curp->name] = data_type;
|
||||
data_type_t*use_type = data_type;
|
||||
|
||||
if (curp->index.size() > 0) {
|
||||
list<pform_range_t>*pd = new list<pform_range_t> (curp->index);
|
||||
use_type = new uarray_type_t(use_type, pd);
|
||||
}
|
||||
|
||||
if (curp->expr.get()) {
|
||||
VLerror(loc, "sorry: Initialization expressions for properties not implemented.");
|
||||
}
|
||||
|
||||
pform_cur_class->type->properties[curp->name] = use_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -154,31 +154,54 @@ struct vector_type_t : public data_type_t {
|
|||
std::auto_ptr< list<pform_range_t> > pdims;
|
||||
};
|
||||
|
||||
struct array_base_t : public data_type_t {
|
||||
public:
|
||||
inline explicit array_base_t(data_type_t*btype, std::list<pform_range_t>*pd)
|
||||
: base_type(btype), dims(pd) { }
|
||||
|
||||
data_type_t*base_type;
|
||||
std::auto_ptr< list<pform_range_t> > dims;
|
||||
};
|
||||
|
||||
/*
|
||||
* The array_type_t is a generalization of the vector_type_t in that
|
||||
* The parray_type_t is a generalization of the vector_type_t in that
|
||||
* the base type is another general data type. Ultimately, the subtype
|
||||
* must also be packed (as this is a packed array) but that may be
|
||||
* worked out during elaboration.
|
||||
*/
|
||||
struct parray_type_t : public data_type_t {
|
||||
struct parray_type_t : public array_base_t {
|
||||
inline explicit parray_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
|
||||
: base_type(btype), packed_dims(pd) { }
|
||||
: array_base_t(btype, pd) { }
|
||||
|
||||
virtual ivl_variable_type_t figure_packed_base_type(void)const;
|
||||
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
data_type_t*base_type;
|
||||
std::auto_ptr< list<pform_range_t> > packed_dims;
|
||||
/*
|
||||
* The uarray_type_t represents unpacked array types.
|
||||
*/
|
||||
struct uarray_type_t : public array_base_t {
|
||||
inline explicit uarray_type_t(data_type_t*btype, std::list<pform_range_t>*pd)
|
||||
: array_base_t(btype, pd) { }
|
||||
|
||||
public:
|
||||
virtual void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
virtual ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
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 {
|
||||
inline explicit string_type_t() { }
|
||||
~string_type_t();
|
||||
|
||||
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
struct class_type_t : public data_type_t {
|
||||
|
|
@ -189,8 +212,9 @@ struct class_type_t : public data_type_t {
|
|||
void pform_dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
perm_string name;
|
||||
|
||||
std::map<perm_string, data_type_t*> properties;
|
||||
|
||||
ivl_type_s* elaborate_type(Design*, NetScope*) const;
|
||||
};
|
||||
|
||||
class property_qualifier_t {
|
||||
|
|
|
|||
|
|
@ -2896,3 +2896,8 @@ extern "C" ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx)
|
|||
|
||||
return class_type->get_prop_type(idx);
|
||||
}
|
||||
|
||||
extern "C" int ivl_type_signed(ivl_type_t net)
|
||||
{
|
||||
return net->get_signed()? 1 : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -209,9 +209,18 @@ static void show_property_expression(ivl_expr_t net, unsigned ind)
|
|||
{
|
||||
ivl_signal_t sig = ivl_expr_signal(net);
|
||||
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>\n", ind, "",
|
||||
ivl_signal_basename(sig), pnam, ivl_expr_width(net));
|
||||
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 if (ivl_expr_value(net) == IVL_VT_STRING) {
|
||||
fprintf(out, "%*s<property base=%s, prop=%s, string>\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)));
|
||||
|
|
|
|||
|
|
@ -24,10 +24,52 @@
|
|||
# include <assert.h>
|
||||
# include <inttypes.h>
|
||||
|
||||
static void show_prop_type_vector(ivl_type_t ptype)
|
||||
{
|
||||
ivl_variable_type_t data_type = ivl_type_base(ptype);
|
||||
unsigned packed_dimensions = ivl_type_packed_dimensions(ptype);
|
||||
assert(packed_dimensions < 2);
|
||||
|
||||
char*signed_flag = ivl_type_signed(ptype)? "s" : "";
|
||||
char code = data_type==IVL_VT_BOOL? 'b' : 'L';
|
||||
|
||||
if (packed_dimensions == 0) {
|
||||
fprintf(vvp_out, "\"%s%c1\"", signed_flag, code);
|
||||
|
||||
} else {
|
||||
assert(packed_dimensions == 1);
|
||||
assert(ivl_type_packed_lsb(ptype,0) == 0);
|
||||
assert(ivl_type_packed_msb(ptype,0) >= 0);
|
||||
|
||||
fprintf(vvp_out, "\"%s%c%d\"", signed_flag, code,
|
||||
ivl_type_packed_msb(ptype,0)+1);
|
||||
}
|
||||
}
|
||||
|
||||
static void show_prop_type(ivl_type_t ptype)
|
||||
{
|
||||
// XXXX: For now, assume all properties are 32bit integers.
|
||||
fprintf(vvp_out, "\"b32\"");
|
||||
ivl_variable_type_t data_type = ivl_type_base(ptype);
|
||||
|
||||
switch (data_type) {
|
||||
case IVL_VT_REAL:
|
||||
fprintf(vvp_out, "\"r\"");
|
||||
break;
|
||||
case IVL_VT_STRING:
|
||||
fprintf(vvp_out, "\"S\"");
|
||||
break;
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC:
|
||||
show_prop_type_vector(ptype);
|
||||
break;
|
||||
case IVL_VT_DARRAY:
|
||||
case IVL_VT_CLASS:
|
||||
fprintf(vvp_out, "\"o\"");
|
||||
break;
|
||||
default:
|
||||
fprintf(vvp_out, "\"<ERROR-no-type>\"");
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_class_in_scope(ivl_type_t classtype)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,16 @@ static int eval_object_null(ivl_expr_t ex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int eval_object_property(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/obj %u;\n", pidx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eval_object_signal(ivl_expr_t ex)
|
||||
{
|
||||
ivl_signal_t sig = ivl_expr_signal(ex);
|
||||
|
|
@ -106,6 +116,9 @@ int draw_eval_object(ivl_expr_t ex)
|
|||
case IVL_EX_NULL:
|
||||
return eval_object_null(ex);
|
||||
|
||||
case IVL_EX_PROPERTY:
|
||||
return eval_object_property(ex);
|
||||
|
||||
case IVL_EX_SIGNAL:
|
||||
return eval_object_signal(ex);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -60,6 +60,15 @@ static void string_ex_concat(ivl_expr_t expr)
|
|||
}
|
||||
}
|
||||
|
||||
static void string_ex_property(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/str %u;\n", pidx);
|
||||
}
|
||||
|
||||
static void string_ex_signal(ivl_expr_t expr)
|
||||
{
|
||||
ivl_signal_t sig = ivl_expr_signal(expr);
|
||||
|
|
@ -100,6 +109,22 @@ static void string_ex_select(ivl_expr_t expr)
|
|||
fprintf(vvp_out, " %%load/dar/str v%p_0;\n", sig);
|
||||
}
|
||||
|
||||
static void string_ex_string(ivl_expr_t expr)
|
||||
{
|
||||
const char*val = ivl_expr_string(expr);
|
||||
|
||||
/* Special case: The elaborator converts the string "" to an
|
||||
8-bit zero, which is in turn escaped to the 4-character
|
||||
string \000. Detect this special case and convert it back
|
||||
to an empty string. [Perhaps elaboration should be fixed?] */
|
||||
if (ivl_expr_width(expr)==8 && (strcmp(val,"\\000") == 0)) {
|
||||
fprintf(vvp_out, " %%pushi/str \"\";\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%pushi/str \"%s\";\n", val);
|
||||
}
|
||||
|
||||
static void string_ex_substr(ivl_expr_t expr)
|
||||
{
|
||||
ivl_expr_t arg;
|
||||
|
|
@ -129,7 +154,7 @@ void draw_eval_string(ivl_expr_t expr)
|
|||
|
||||
switch (ivl_expr_type(expr)) {
|
||||
case IVL_EX_STRING:
|
||||
fprintf(vvp_out, " %%pushi/str \"%s\";\n", ivl_expr_string(expr));
|
||||
string_ex_string(expr);
|
||||
break;
|
||||
|
||||
case IVL_EX_SIGNAL:
|
||||
|
|
@ -140,6 +165,10 @@ void draw_eval_string(ivl_expr_t expr)
|
|||
string_ex_concat(expr);
|
||||
break;
|
||||
|
||||
case IVL_EX_PROPERTY:
|
||||
string_ex_property(expr);
|
||||
break;
|
||||
|
||||
case IVL_EX_SELECT:
|
||||
string_ex_select(expr);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -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,62 @@ 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 if (ivl_type_base(prop_type) == IVL_VT_STRING) {
|
||||
|
||||
/* Calculate the string value into the string value
|
||||
stack. The %store/prop/r will pop the stack
|
||||
value. */
|
||||
draw_eval_string(rval);
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
fprintf(vvp_out, " %%store/prop/str %d;\n", prop_idx);
|
||||
fprintf(vvp_out, " %%pop/obj 1;\n");
|
||||
|
||||
} else if (ivl_type_base(prop_type) == IVL_VT_DARRAY) {
|
||||
|
||||
/* The property is a darray, and there is no mux
|
||||
expression to the assignment is of an entire
|
||||
array object. */
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
draw_eval_object(rval);
|
||||
fprintf(vvp_out, " %%store/prop/obj %d;\n", prop_idx);
|
||||
fprintf(vvp_out, " %%pop/obj 1;\n");
|
||||
|
||||
} else if (ivl_type_base(prop_type) == IVL_VT_CLASS) {
|
||||
|
||||
/* The property is a class object. */
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
draw_eval_object(rval);
|
||||
fprintf(vvp_out, " %%store/prop/obj %d;\n", prop_idx);
|
||||
fprintf(vvp_out, " %%pop/obj 1;\n");
|
||||
|
||||
} else {
|
||||
fprintf(vvp_out, " ; ERROR: ivl_type_base(prop_type) = %d\n",
|
||||
ivl_type_base(prop_type));
|
||||
assert(0);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* There is no property select, so evaluate the r-value
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
# include "compile.h"
|
||||
# include "vpi_priv.h"
|
||||
# include "config.h"
|
||||
# include <map>
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
# include "vvp_cleanup.h"
|
||||
#endif
|
||||
|
|
@ -28,15 +29,376 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
class_type::class_type(const string&nam, size_t nprop)
|
||||
: class_name_(nam), properties_(nprop)
|
||||
/*
|
||||
* This class_property_t class is an abstract base class for
|
||||
* representing a property of an instance. The definition keeps and
|
||||
* array (of pointers) of these in order to define the the class.
|
||||
*/
|
||||
class class_property_t {
|
||||
public:
|
||||
explicit inline class_property_t() { }
|
||||
virtual ~class_property_t() =0;
|
||||
// How much space does an instance of this property require?
|
||||
virtual size_t instance_size() const =0;
|
||||
|
||||
void set_offset(size_t off) { offset_ = off; }
|
||||
|
||||
public:
|
||||
virtual void construct(char*buf) const;
|
||||
virtual void destruct(char*buf) const;
|
||||
|
||||
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);
|
||||
|
||||
virtual void set_string(char*buf, const std::string&val);
|
||||
virtual string get_string(char*buf);
|
||||
|
||||
virtual void set_object(char*buf, const vvp_object_t&val);
|
||||
virtual void get_object(char*buf, vvp_object_t&val);
|
||||
|
||||
protected:
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
class_property_t::~class_property_t()
|
||||
{
|
||||
}
|
||||
|
||||
void class_type::set_property(size_t idx, const string&name)
|
||||
void class_property_t::construct(char*) const
|
||||
{
|
||||
}
|
||||
|
||||
void class_property_t::destruct(char*) const
|
||||
{
|
||||
}
|
||||
|
||||
void class_property_t::set_vec4(char*, const vvp_vector4_t&)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void class_property_t::set_string(char*, const string&)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
string class_property_t::get_string(char*)
|
||||
{
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
void class_property_t::set_object(char*, const vvp_object_t&)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void class_property_t::get_object(char*, vvp_object_t&)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
template <class T> class property_atom : public class_property_t {
|
||||
public:
|
||||
inline explicit property_atom(void) { }
|
||||
~property_atom() { }
|
||||
|
||||
size_t instance_size() const { return sizeof(T); }
|
||||
|
||||
public:
|
||||
void construct(char*buf) const
|
||||
{ T*tmp = reinterpret_cast<T*> (buf+offset_);
|
||||
*tmp = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
class property_string : public class_property_t {
|
||||
public:
|
||||
inline explicit property_string(void) { }
|
||||
~property_string() { }
|
||||
|
||||
size_t instance_size() const { return sizeof(std::string); }
|
||||
|
||||
public:
|
||||
void construct(char*buf) const
|
||||
{ /* string*tmp = */ new (buf+offset_) string; }
|
||||
|
||||
void destruct(char*buf) const
|
||||
{ string*tmp = reinterpret_cast<string*> (buf+offset_);
|
||||
tmp->~string();
|
||||
}
|
||||
|
||||
void set_string(char*buf, const string&);
|
||||
string get_string(char*buf);
|
||||
};
|
||||
|
||||
class property_object : public class_property_t {
|
||||
public:
|
||||
inline explicit property_object(void) { }
|
||||
~property_object() { }
|
||||
|
||||
size_t instance_size() const { return sizeof(vvp_object_t); }
|
||||
|
||||
public:
|
||||
void construct(char*buf) const
|
||||
{ /* vvp_object_t*tmp = */ new (buf+offset_) vvp_object_t; }
|
||||
|
||||
void destruct(char*buf) const
|
||||
{ vvp_object_t*tmp = reinterpret_cast<vvp_object_t*> (buf+offset_);
|
||||
tmp->~vvp_object_t();
|
||||
}
|
||||
|
||||
void set_object(char*buf, const vvp_object_t&);
|
||||
void get_object(char*buf, vvp_object_t&);
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void property_string::set_string(char*buf, const string&val)
|
||||
{
|
||||
string*tmp = reinterpret_cast<string*>(buf+offset_);
|
||||
*tmp = val;
|
||||
}
|
||||
|
||||
string property_string::get_string(char*buf)
|
||||
{
|
||||
string*tmp = reinterpret_cast<string*>(buf+offset_);
|
||||
return *tmp;
|
||||
}
|
||||
|
||||
void property_object::set_object(char*buf, const vvp_object_t&val)
|
||||
{
|
||||
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
|
||||
*tmp = val;
|
||||
}
|
||||
|
||||
void property_object::get_object(char*buf, vvp_object_t&val)
|
||||
{
|
||||
vvp_object_t*tmp = reinterpret_cast<vvp_object_t*>(buf+offset_);
|
||||
val = *tmp;
|
||||
}
|
||||
|
||||
|
||||
/* **** */
|
||||
|
||||
class_type::class_type(const string&nam, size_t nprop)
|
||||
: class_name_(nam), properties_(nprop)
|
||||
{
|
||||
instance_size_ = 0;
|
||||
}
|
||||
|
||||
void class_type::set_property(size_t idx, const string&name, const string&type)
|
||||
{
|
||||
assert(idx < properties_.size());
|
||||
properties_[idx].name = name;
|
||||
|
||||
if (type == "b8")
|
||||
properties_[idx].type = new property_atom<uint8_t>;
|
||||
else if (type == "b16")
|
||||
properties_[idx].type = new property_atom<uint16_t>;
|
||||
else if (type == "b32")
|
||||
properties_[idx].type = new property_atom<uint32_t>;
|
||||
else if (type == "b64")
|
||||
properties_[idx].type = new property_atom<uint64_t>;
|
||||
else if (type == "sb8")
|
||||
properties_[idx].type = new property_atom<int8_t>;
|
||||
else if (type == "sb16")
|
||||
properties_[idx].type = new property_atom<int16_t>;
|
||||
else if (type == "sb32")
|
||||
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 if (type == "S")
|
||||
properties_[idx].type = new property_string;
|
||||
else if (type == "o")
|
||||
properties_[idx].type = new property_object;
|
||||
else
|
||||
properties_[idx].type = 0;
|
||||
}
|
||||
|
||||
void class_type::finish_setup(void)
|
||||
{
|
||||
map<size_t, vector<size_t> > size_map;
|
||||
// Add up all the sizes to get a total instance size. This
|
||||
// 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);
|
||||
}
|
||||
|
||||
instance_size_ = accum;
|
||||
|
||||
// Now allocate the properties to offsets within an instance
|
||||
// space. Allocate the properties largest objects first so
|
||||
// that they are assured better alignment.
|
||||
accum = 0;
|
||||
for (map<size_t, vector<size_t> >::reverse_iterator cur = size_map.rbegin()
|
||||
; cur != size_map.rend() ; ++ cur) {
|
||||
for (size_t idx = 0 ; idx < cur->second.size() ; idx += 1) {
|
||||
size_t pid = cur->second[idx];
|
||||
class_property_t*ptype = properties_[pid].type;
|
||||
assert(ptype->instance_size() == cur->first);
|
||||
ptype->set_offset(accum);
|
||||
accum += cur->first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_type::inst_t class_type::instance_new() const
|
||||
{
|
||||
char*buf = new char [instance_size_];
|
||||
|
||||
for (size_t idx = 0 ; idx < properties_.size() ; idx += 1)
|
||||
properties_[idx].type->construct(buf);
|
||||
|
||||
return reinterpret_cast<inst_t> (buf);
|
||||
}
|
||||
|
||||
void class_type::instance_delete(class_type::inst_t obj) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
|
||||
for (size_t idx = 0 ; idx < properties_.size() ; idx += 1)
|
||||
properties_[idx].type->destruct(buf);
|
||||
|
||||
delete[]buf;
|
||||
}
|
||||
|
||||
void class_type::set_vec4(class_type::inst_t obj, size_t pid,
|
||||
const vvp_vector4_t&val) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
properties_[pid].type->set_vec4(buf, val);
|
||||
}
|
||||
|
||||
void class_type::get_vec4(class_type::inst_t obj, size_t pid,
|
||||
vvp_vector4_t&val) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
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);
|
||||
}
|
||||
|
||||
void class_type::set_string(class_type::inst_t obj, size_t pid,
|
||||
const string&val) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
properties_[pid].type->set_string(buf, val);
|
||||
}
|
||||
|
||||
string class_type::get_string(class_type::inst_t obj, size_t pid) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
return properties_[pid].type->get_string(buf);
|
||||
}
|
||||
|
||||
void class_type::set_object(class_type::inst_t obj, size_t pid,
|
||||
const vvp_object_t&val) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
properties_[pid].type->set_object(buf, val);
|
||||
}
|
||||
|
||||
void class_type::get_object(class_type::inst_t obj, size_t pid, vvp_object_t&val) const
|
||||
{
|
||||
char*buf = reinterpret_cast<char*> (obj);
|
||||
assert(pid < properties_.size());
|
||||
properties_[pid].type->get_object(buf, val);
|
||||
}
|
||||
|
||||
int class_type::get_type_code(void) const
|
||||
|
|
@ -58,7 +420,7 @@ void compile_class_start(char*lab, char*nam, unsigned ntype)
|
|||
void compile_class_property(unsigned idx, char*nam, char*typ)
|
||||
{
|
||||
assert(compile_class);
|
||||
compile_class->set_property(idx, nam);
|
||||
compile_class->set_property(idx, nam, typ);
|
||||
delete[]nam;
|
||||
delete[]typ;
|
||||
}
|
||||
|
|
@ -67,6 +429,8 @@ void compile_class_done(void)
|
|||
{
|
||||
struct __vpiScope*scope = vpip_peek_current_scope();
|
||||
assert(scope);
|
||||
assert(compile_class);
|
||||
compile_class->finish_setup();
|
||||
scope->classes[compile_class->class_name()] = compile_class;
|
||||
compile_class = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -23,6 +23,9 @@
|
|||
# include <vector>
|
||||
# include "vpi_priv.h"
|
||||
|
||||
class class_property_t;
|
||||
class vvp_vector4_t;
|
||||
|
||||
/*
|
||||
* This represents the TYPE information for a class. A %new operator
|
||||
* uses this information to figure out how to construct an actual
|
||||
|
|
@ -30,6 +33,10 @@
|
|||
*/
|
||||
class class_type : public __vpiHandle {
|
||||
|
||||
public:
|
||||
struct inst_x;
|
||||
typedef inst_x*inst_t;
|
||||
|
||||
public:
|
||||
explicit class_type(const std::string&nam, size_t nprop);
|
||||
|
||||
|
|
@ -41,8 +48,27 @@ class class_type : public __vpiHandle {
|
|||
// Set the details about the property. This is used during
|
||||
// parse of the .vvp file to fill in the details of the
|
||||
// property for the class definition.
|
||||
void set_property(size_t idx, const std::string&name);
|
||||
void set_property(size_t idx, const std::string&name, const std::string&type);
|
||||
|
||||
// This method is called after all the properties are
|
||||
// defined. This calculates information about the defintion.
|
||||
void finish_setup(void);
|
||||
|
||||
public:
|
||||
// Constructures and destructors for making instances.
|
||||
inst_t instance_new() const;
|
||||
void instance_delete(inst_t) 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 set_real(inst_t inst, size_t pid, double val) const;
|
||||
double get_real(inst_t inst, size_t pid) const;
|
||||
void set_string(inst_t inst, size_t pid, const std::string&val) const;
|
||||
std::string get_string(inst_t inst, size_t pid) const;
|
||||
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;
|
||||
|
||||
public: // VPI related methods
|
||||
int get_type_code(void) const;
|
||||
|
||||
private:
|
||||
|
|
@ -50,8 +76,10 @@ class class_type : public __vpiHandle {
|
|||
|
||||
struct prop_t {
|
||||
std::string name;
|
||||
class_property_t*type;
|
||||
};
|
||||
std::vector<prop_t> properties_;
|
||||
size_t instance_size_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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,15 @@ 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_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_PROP_R(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_PROP_STR(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 +187,9 @@ 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_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_STR(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);
|
||||
|
|
|
|||
|
|
@ -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,12 +207,16 @@ 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/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%prop/obj",of_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%prop/str",of_PROP_STR,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} },
|
||||
{ "%pushv/str", of_PUSHV_STR, 2, {OA_BIT1,OA_BIT2, OA_NONE} },
|
||||
|
|
@ -230,7 +234,10 @@ 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/v",of_STORE_PROP_V,3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%store/prop/obj",of_STORE_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%store/prop/r", of_STORE_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%store/prop/str",of_STORE_PROP_STR,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} },
|
||||
{ "%store/str", of_STORE_STR, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
|
|
|
|||
|
|
@ -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,15 @@ This opcode raises the left operand by the right operand, and pushes
|
|||
the result.
|
||||
|
||||
* %prop/v <pid>, <base>, <wid>
|
||||
* %prop/obj <pid>
|
||||
* %prop/r <pid>
|
||||
* %prop/str <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) or string (/str) into
|
||||
property number <pid> of the class object on the top of the object
|
||||
stack.
|
||||
|
||||
The class object stack is NOT popped.
|
||||
|
||||
* %pushi/real <mant>, <exp>
|
||||
|
||||
|
|
@ -1009,6 +1017,19 @@ variable given by the label.
|
|||
|
||||
See also %load/obj.
|
||||
|
||||
* %store/prop/obj <index>
|
||||
* %store/prop/r <index>
|
||||
* %store/prop/str <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.
|
||||
|
||||
The %store/prop/obj pops an object from the top of the object stack,
|
||||
then writes it to the property number <index> of the cobject now on
|
||||
top of the object stack. The cobject is NOT popped.
|
||||
|
||||
* %store/real <var-label>
|
||||
* %store/reala <var-label>, <index>
|
||||
|
||||
|
|
|
|||
142
vvp/vthread.cc
142
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);
|
||||
|
|
@ -3219,6 +3226,7 @@ bool of_LOAD_DAR(vthread_t thr, vvp_code_t cp)
|
|||
darray->get_word(adr, word);
|
||||
assert(word.size() == wid);
|
||||
|
||||
thr_check_addr(thr, bit+word.size());
|
||||
thr->bits4.set_vec(bit, word);
|
||||
|
||||
return true;
|
||||
|
|
@ -4414,6 +4422,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 +4534,64 @@ bool of_POW_WR(vthread_t thr, vvp_code_t)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %prop/obj <pid>
|
||||
*
|
||||
* Load an object value from the cobject and push it onto the object stack.
|
||||
*/
|
||||
bool of_PROP_OBJ(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>();
|
||||
|
||||
vvp_object_t val;
|
||||
cobj->get_object(pid, val);
|
||||
|
||||
thr->push_object(val);
|
||||
|
||||
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/str <pid>
|
||||
*
|
||||
* Load a string value from the cobject and push it onto the real value
|
||||
* stack.
|
||||
*/
|
||||
bool of_PROP_STR(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>();
|
||||
|
||||
string val = cobj->get_string(pid);
|
||||
thr->push_str(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %prop/v <pid> <base> <wid>
|
||||
*
|
||||
|
|
@ -5057,6 +5133,70 @@ bool of_STORE_OBJ(vthread_t thr, vvp_code_t cp)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/prop/obj <id>
|
||||
*
|
||||
* Pop an object value from the object 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_OBJ(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
size_t pid = cp->number;
|
||||
vvp_object_t val;
|
||||
thr->pop_object(val);
|
||||
|
||||
vvp_object_t&obj = thr->peek_object();
|
||||
vvp_cobject*cobj = obj.peek<vvp_cobject>();
|
||||
assert(cobj);
|
||||
|
||||
cobj->set_object(pid, val);
|
||||
|
||||
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/str <id>
|
||||
*
|
||||
* Pop a string value from the string 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_STR(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
size_t pid = cp->number;
|
||||
string val = thr->pop_str();
|
||||
|
||||
vvp_object_t&obj = thr->peek_object();
|
||||
vvp_cobject*cobj = obj.peek<vvp_cobject>();
|
||||
assert(cobj);
|
||||
|
||||
cobj->set_string(pid, val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %store/prop/v <id> <base> <wid>
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -25,33 +25,52 @@
|
|||
using namespace std;
|
||||
|
||||
vvp_cobject::vvp_cobject(const class_type*defn)
|
||||
: defn_(defn), properties_(new int32_t[defn->property_count()])
|
||||
: defn_(defn), properties_(defn->instance_new())
|
||||
{
|
||||
}
|
||||
|
||||
vvp_cobject::~vvp_cobject()
|
||||
{
|
||||
delete[]properties_;
|
||||
defn_->instance_delete(properties_);
|
||||
properties_ = 0;
|
||||
}
|
||||
|
||||
void vvp_cobject::set_vec4(size_t pid, const vvp_vector4_t&val)
|
||||
{
|
||||
assert(pid < defn_->property_count());
|
||||
|
||||
int32_t tmp;
|
||||
bool flag = vector4_to_value(val, tmp, true, false);
|
||||
assert(flag);
|
||||
|
||||
properties_[pid] = tmp;
|
||||
defn_->set_vec4(properties_, pid, val);
|
||||
}
|
||||
|
||||
void vvp_cobject::get_vec4(size_t pid, vvp_vector4_t&val)
|
||||
{
|
||||
assert(pid < defn_->property_count());
|
||||
|
||||
unsigned long tmp[1];
|
||||
tmp[0] = properties_[pid];
|
||||
val.resize(32);
|
||||
val.setarray(0, 32, tmp);
|
||||
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);
|
||||
}
|
||||
|
||||
void vvp_cobject::set_string(size_t pid, const string&val)
|
||||
{
|
||||
defn_->set_string(properties_, pid, val);
|
||||
}
|
||||
|
||||
string vvp_cobject::get_string(size_t pid)
|
||||
{
|
||||
return defn_->get_string(properties_, pid);
|
||||
}
|
||||
|
||||
void vvp_cobject::set_object(size_t pid, const vvp_object_t&val)
|
||||
{
|
||||
defn_->set_object(properties_, pid, val);
|
||||
}
|
||||
|
||||
void vvp_cobject::get_object(size_t pid, vvp_object_t&val)
|
||||
{
|
||||
return defn_->get_object(properties_, pid, val);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -19,10 +19,11 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include <string>
|
||||
# include <stdint.h>
|
||||
# include "vvp_object.h"
|
||||
# include "class_type.h"
|
||||
|
||||
class class_type;
|
||||
class vvp_vector4_t;
|
||||
|
||||
class vvp_cobject : public vvp_object {
|
||||
|
|
@ -34,10 +35,19 @@ 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);
|
||||
|
||||
void set_string(size_t pid, const std::string&val);
|
||||
std::string get_string(size_t pid);
|
||||
|
||||
void set_object(size_t pid, const vvp_object_t&val);
|
||||
void get_object(size_t pid, vvp_object_t&val);
|
||||
|
||||
private:
|
||||
const class_type* defn_;
|
||||
// For now, only support 32bit bool signed properties.
|
||||
int32_t*properties_;
|
||||
class_type::inst_t properties_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue