Implement $bits(type) to get the size of a type

In the process, I implemented a means to get at
previously elaborated types from the pform type
pointer.
This commit is contained in:
Stephen Williams 2013-12-16 04:36:13 +02:00
parent 8a4d769b3d
commit 6ec31517a9
8 changed files with 63 additions and 33 deletions

View File

@ -671,6 +671,8 @@ class PETypename : public PExpr {
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
ivl_type_t type, unsigned flags) const;
inline data_type_t* get_type() const { return data_type_; }
private:
data_type_t*data_type_;
};

View File

@ -65,7 +65,7 @@ void PFunction::push_statement_front(Statement*stmt)
blk->push_statement_front(stmt);
}
void PFunction::set_return(const data_type_t*t)
void PFunction::set_return(data_type_t*t)
{
return_type_ = t;
}

View File

@ -114,7 +114,7 @@ class PFunction : public PTaskFunc {
~PFunction();
void set_statement(Statement *s);
void set_return(const data_type_t*t);
void set_return(data_type_t*t);
inline Statement* get_statement() { return statement_; }
@ -141,7 +141,7 @@ class PFunction : public PTaskFunc {
void dump(ostream&, unsigned) const;
private:
const data_type_t* return_type_;
data_type_t* return_type_;
Statement *statement_;
bool is_auto_;
};

View File

@ -1397,19 +1397,30 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope,
PExpr*expr = parms_[0];
uint64_t use_width = 0;
if (PETypename*type_expr = dynamic_cast<PETypename*>(expr)) {
cerr << get_fileline() << ": sorry: "
<< "I don't yet support typename argumets to $bits." << endl;
des->errors += 1;
return 0;
ivl_type_t tmp_type = type_expr->get_type()->elaborate_type(des, scope);
ivl_assert(*this, tmp_type);
use_width = tmp_type->packed_width();
if (debug_elaborate) {
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
<< " Packed width of type argument is " << use_width << endl;
}
} else {
verinum val ( (uint64_t)expr->expr_width(), integer_width);
use_width = expr->expr_width();
if (debug_elaborate) {
cerr << get_fileline() << ": PECallFunction::elaborate_sfunc_: "
<< " Width of expression argument is " << use_width << endl;
}
}
verinum val (use_width, integer_width);
NetEConst*sub = new NetEConst(val);
sub->set_line(*this);
return cast_to_width_(sub, expr_wid);
}
}
/* Interpret the internal $is_signed system function to return
a single bit flag -- 1 if the expression is signed, 0

View File

@ -876,7 +876,7 @@ static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
data_type_t*pform_type)
{
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(pform_type)) {
netstruct_t*use_type = struct_type->elaborate_type(des, scope);
ivl_type_s*use_type = struct_type->elaborate_type(des, scope);
return use_type;
}
@ -1210,7 +1210,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
} else if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(set_data_type_)) {
// If this is a struct type, then build the net with the
// struct type.
netstruct_t*use_type = struct_type->elaborate_type(des, scope);
ivl_type_s*tmp_type = struct_type->elaborate_type(des, scope);
netstruct_t*use_type = dynamic_cast<netstruct_t*>(tmp_type);
if (debug_elaborate) {
cerr << get_fileline() << ": debug: Create signal " << wtype;
if (use_type->packed())

View File

@ -31,7 +31,7 @@
using namespace std;
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*) const
ivl_type_s* data_type_t::elaborate_type_raw(Design*des, NetScope*) const
{
cerr << get_fileline() << ": internal error: "
<< "Elaborate method not implemented for " << typeid(*this).name()
@ -40,7 +40,7 @@ ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*) const
return 0;
}
ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
ivl_type_s* atom2_type_t::elaborate_type_raw(Design*des, NetScope*) const
{
switch (type_code) {
case 64:
@ -75,18 +75,18 @@ ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
}
}
ivl_type_s* class_type_t::elaborate_type(Design*, NetScope*scope) const
ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*scope) const
{
return scope->find_class(name);
}
ivl_type_s* enum_type_t::elaborate_type(Design*des, NetScope*scope) const
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
ivl_assert(*this, net_type);
return net_type;
}
ivl_type_s* vector_type_t::elaborate_type(Design*des, NetScope*scope) const
ivl_type_s* vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
vector<netrange_t> packed;
@ -122,7 +122,7 @@ ivl_type_s* vector_type_t::elaborate_type(Design*des, NetScope*scope) const
return tmp;
}
ivl_type_s* real_type_t::elaborate_type(Design*, NetScope*) const
ivl_type_s* real_type_t::elaborate_type_raw(Design*, NetScope*) const
{
switch (type_code) {
case REAL:
@ -133,12 +133,12 @@ ivl_type_s* real_type_t::elaborate_type(Design*, NetScope*) const
return 0;
}
ivl_type_s* string_type_t::elaborate_type(Design*, NetScope*) const
ivl_type_s* string_type_t::elaborate_type_raw(Design*, NetScope*) const
{
return &netstring_t::type_string;
}
netstruct_t* struct_type_t::elaborate_type(Design*des, NetScope*scope) const
netstruct_t* struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
netstruct_t*res = new netstruct_t;
@ -173,7 +173,7 @@ netstruct_t* struct_type_t::elaborate_type(Design*des, NetScope*scope) const
return res;
}
ivl_type_s* uarray_type_t::elaborate_type(Design*des, NetScope*scope) const
ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
{
ivl_type_t btype = base_type->elaborate_type(des, scope);

View File

@ -24,6 +24,15 @@ data_type_t::~data_type_t()
{
}
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
{
if (cache_type_elaborate_)
return cache_type_elaborate_;
cache_type_elaborate_ = elaborate_type_raw(des, scope);
return cache_type_elaborate_;
}
string_type_t::~string_type_t()
{
}

View File

@ -88,14 +88,21 @@ struct pform_tf_port_t {
*/
class data_type_t : public LineInfo {
public:
inline explicit data_type_t() : cache_type_elaborate_(0) { }
virtual ~data_type_t() = 0;
// This method is used to figure out the base type of a packed
// compound object. Return IVL_VT_NO_TYPE if the type is not packed.
virtual ivl_variable_type_t figure_packed_base_type(void)const;
// This method is used by the pform dumper to diagnostic dump.
virtual void pform_dump(std::ostream&out, unsigned indent) const;
ivl_type_s* elaborate_type(Design*des, NetScope*scope);
private:
// Elaborate the type to an ivl_type_s type.
virtual ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
ivl_type_s*cache_type_elaborate_;
};
struct void_type_t : public data_type_t {
@ -111,7 +118,7 @@ struct void_type_t : public data_type_t {
struct enum_type_t : public data_type_t {
inline enum_type_t(void) : net_type(0) { }
// Return the elaborated version of the type.
virtual ivl_type_s*elaborate_type(Design*des, NetScope*scope) const;
virtual ivl_type_s*elaborate_type_raw(Design*des, NetScope*scope) const;
ivl_variable_type_t base_type;
bool signed_flag;
@ -134,7 +141,7 @@ struct struct_member_t : public LineInfo {
struct struct_type_t : public data_type_t {
virtual ivl_variable_type_t figure_packed_base_type(void)const;
virtual void pform_dump(std::ostream&out, unsigned indent) const;
virtual netstruct_t* elaborate_type(Design*des, NetScope*scope) const;
virtual netstruct_t* elaborate_type_raw(Design*des, NetScope*scope) const;
bool packed_flag;
bool union_flag;
@ -147,7 +154,7 @@ struct atom2_type_t : public data_type_t {
int type_code;
bool signed_flag;
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
};
/*
@ -174,7 +181,7 @@ struct vector_type_t : public data_type_t {
std::list<pform_range_t>*pd)
: base_type(bt), signed_flag(sf), reg_flag(false), integer_flag(false), implicit_flag(false), pdims(pd) { }
virtual ivl_variable_type_t figure_packed_base_type(void)const;
ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
ivl_variable_type_t base_type;
bool signed_flag;
@ -216,7 +223,7 @@ struct uarray_type_t : public array_base_t {
public:
virtual void pform_dump(std::ostream&out, unsigned indent) const;
virtual ivl_type_s* elaborate_type(Design*des, NetScope*scope) const;
virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
};
struct real_type_t : public data_type_t {
@ -224,14 +231,14 @@ struct real_type_t : public data_type_t {
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;
ivl_type_s* elaborate_type_raw(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;
ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
};
struct class_type_t : public data_type_t {
@ -271,7 +278,7 @@ struct class_type_t : public data_type_t {
// without waiting for any constructor.
std::vector<Statement*> initialize_static;
ivl_type_s* elaborate_type(Design*, NetScope*) const;
ivl_type_s* elaborate_type_raw(Design*, NetScope*) const;
};
/*