Merge branch 'x-mil6'

This commit is contained in:
Stephen Williams 2013-01-30 17:03:19 -08:00
commit ee58fd749c
33 changed files with 1164 additions and 83 deletions

View File

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

View File

@ -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,

View File

@ -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
{

View File

@ -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;
}

View File

@ -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);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -19,6 +19,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;
}

View File

@ -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. */

View File

@ -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

View 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);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -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)

View File

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

44
netscalar.cc Normal file
View File

@ -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;
}

49
netscalar.h Normal file
View File

@ -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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -21,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)

View File

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

View File

@ -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")

View File

@ -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;
}
}

View File

@ -1,7 +1,7 @@
#ifndef __pform_types_H
#define __pform_types_H
/*
* Copyright (c) 2007-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2007-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -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 {

View File

@ -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;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2007-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -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)));

View File

@ -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)

View File

@ -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);

View File

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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 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;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2011,2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -846,16 +846,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

View File

@ -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;
}

View File

@ -1,7 +1,7 @@
#ifndef __class_type_H
#define __class_type_H
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -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

View File

@ -1,7 +1,7 @@
#ifndef __codes_H
#define __codes_H
/*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -159,11 +159,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);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -207,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} },

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
*
*/
@ -865,11 +865,13 @@ or sign extending a vector.
* %pop/str <num>
* %pop/real <num>
* %pop/obj <num>
Pop this many items from the string stack. This is the opposite of the
%pushX/str opcode which pushes a string to the stack. The %pop/str is
not normally needed because the %store/str includes an implicit pop,
but sometimes it is necessary to pop explicitly.
Pop this many items from the string/real/object stack. This is the
opposite of the %pushX/str opcode which pushes a string to the
stack. The %pop/str is not normally needed because the %store/str
includes an implicit pop, but sometimes it is necessary to pop
explicitly.
* %pow <bit-l>, <bit-r>, <wid>
* %pow/s <bit-l>, <bit-r>, <wid>
@ -887,9 +889,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>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -182,6 +182,13 @@ struct vthread_s {
obj = stack_obj_[stack_obj_size_];
stack_obj_[stack_obj_size_].reset(0);
}
inline void pop_object(unsigned cnt)
{
assert(cnt <= stack_obj_size_);
for (size_t idx = stack_obj_size_-cnt ; idx < stack_obj_size_ ; idx += 1)
stack_obj_[idx].reset(0);
stack_obj_size_ -= cnt;
}
inline void push_object(const vvp_object_t&obj)
{
assert(stack_obj_size_ < STACK_OBJ_MAX_SIZE);
@ -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>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -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);
}

View File

@ -1,7 +1,7 @@
#ifndef __vvp_cobject_H
#define __vvp_cobject_H
/*
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
* Copyright (c) 2012-2013 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -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