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:
parent
8a4d769b3d
commit
6ec31517a9
2
PExpr.h
2
PExpr.h
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
4
PTask.h
4
PTask.h
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
|||
29
elab_expr.cc
29
elab_expr.cc
|
|
@ -1397,18 +1397,29 @@ 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;
|
||||
} else {
|
||||
verinum val ( (uint64_t)expr->expr_width(), integer_width);
|
||||
NetEConst*sub = new NetEConst(val);
|
||||
sub->set_line(*this);
|
||||
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;
|
||||
}
|
||||
|
||||
return cast_to_width_(sub, expr_wid);
|
||||
} else {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -563,7 +563,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
|||
// Special case: this is a constructor, so the return
|
||||
// signal is also the first argument. For example, the
|
||||
// source code for the definition may be:
|
||||
// function new(...);
|
||||
// function new(...);
|
||||
// endfunction
|
||||
// In this case, the "@" port is the synthetic "this"
|
||||
// argument and we also use it as a return value at the
|
||||
|
|
@ -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())
|
||||
|
|
|
|||
18
elab_type.cc
18
elab_type.cc
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue