diff options
Diffstat (limited to 'src/grt/ghwlib.c')
-rw-r--r-- | src/grt/ghwlib.c | 267 |
1 files changed, 210 insertions, 57 deletions
diff --git a/src/grt/ghwlib.c b/src/grt/ghwlib.c index 7c5b80bd0..ddfab6b57 100644 --- a/src/grt/ghwlib.c +++ b/src/grt/ghwlib.c @@ -391,7 +391,8 @@ ghw_get_base_type (union ghw_type *t) } } -int +/* Return -1 for unbounded types. */ +static int get_nbr_elements (union ghw_type *t) { switch (t->kind) @@ -406,20 +407,21 @@ get_nbr_elements (union ghw_type *t) case ghdl_rtik_type_p64: case ghdl_rtik_subtype_scalar: return 1; + case ghdl_rtik_type_array: + return -1; case ghdl_rtik_subtype_array: - case ghdl_rtik_subtype_array_ptr: - return t->sa.nbr_el; + return t->sa.nbr_scalars; case ghdl_rtik_type_record: - return t->rec.nbr_el; + return t->rec.nbr_scalars; case ghdl_rtik_subtype_record: - return t->sr.base->nbr_el; + return t->sr.nbr_scalars; default: fprintf (stderr, "get_nbr_elements: unhandled type %d\n", t->kind); abort (); } } -int +static int get_range_length (union ghw_range *rng) { switch (rng->kind) @@ -445,6 +447,91 @@ get_range_length (union ghw_range *rng) } } +/* Create an array subtype using BASE and ranges read from H. */ + +struct ghw_subtype_array * +ghw_read_array_subtype (struct ghw_handler *h, struct ghw_type_array *base) +{ + struct ghw_subtype_array *sa; + int j; + int nbr_scalars; + + sa = malloc (sizeof (struct ghw_subtype_array)); + sa->kind = ghdl_rtik_subtype_array; + sa->name = NULL; + sa->base = base; + nbr_scalars = get_nbr_elements (base->el); + sa->rngs = malloc (base->nbr_dim * sizeof (union ghw_range *)); + for (j = 0; j < base->nbr_dim; j++) + { + sa->rngs[j] = ghw_read_range (h); + nbr_scalars *= get_range_length (sa->rngs[j]); + } + sa->nbr_scalars = nbr_scalars; + return sa; +} + +struct ghw_subtype_record * +ghw_read_record_subtype (struct ghw_handler *h, struct ghw_type_record *base) +{ + struct ghw_subtype_record *sr; + + sr = malloc (sizeof (struct ghw_subtype_record)); + sr->kind = ghdl_rtik_subtype_record; + sr->name = NULL; + sr->base = base; + if (base->nbr_scalars >= 0) + { + /* Record base type is bounded. */ + sr->nbr_scalars = base->nbr_scalars; + sr->els = base->els; + } + else + { + /* Read subtypes. */ + int j; + int nbr_scalars; + + sr->els = malloc (base->nbr_fields * sizeof (struct ghw_record_element)); + nbr_scalars = 0; + for (j = 0; j < base->nbr_fields; j++) + { + union ghw_type *btype = base->els[j].type; + int el_nbr_scalars = get_nbr_elements (btype); + + sr->els[j].name = base->els[j].name; + if (el_nbr_scalars >= 0) + { + /* Element is constrained. */ + sr->els[j].type = btype; + } + else + { + switch (btype->kind) + { + case ghdl_rtik_type_array: + sr->els[j].type = (union ghw_type *) + ghw_read_array_subtype (h, &btype->ar); + break; + case ghdl_rtik_type_record: + sr->els[j].type = (union ghw_type *) + ghw_read_record_subtype (h, &btype->rec); + break; + default: + fprintf + (stderr, "ghw_read_record_subtype: unhandled kind %d\n", + btype->kind); + return NULL; + } + el_nbr_scalars = get_nbr_elements (sr->els[j].type); + } + nbr_scalars += el_nbr_scalars; + } + sr->nbr_scalars = nbr_scalars; + } + return sr; +} + int ghw_read_type (struct ghw_handler *h) { @@ -574,66 +661,71 @@ ghw_read_type (struct ghw_handler *h) } break; case ghdl_rtik_subtype_array: - case ghdl_rtik_subtype_array_ptr: { struct ghw_subtype_array *sa; - int j; - int nbr_el; + const char *name; + struct ghw_type_array *base; - sa = malloc (sizeof (struct ghw_subtype_array)); - sa->kind = t; - sa->name = ghw_read_strid (h); - sa->base = (struct ghw_type_array *)ghw_read_typeid (h); - nbr_el = get_nbr_elements (sa->base->el); - sa->rngs = malloc (sa->base->nbr_dim * sizeof (union ghw_range *)); - for (j = 0; j < sa->base->nbr_dim; j++) - { - sa->rngs[j] = ghw_read_range (h); - nbr_el *= get_range_length (sa->rngs[j]); - } - sa->nbr_el = nbr_el; - if (h->flag_verbose > 1) - printf ("subtype array: %s (nbr_el=%d)\n", sa->name, sa->nbr_el); + name = ghw_read_strid (h); + base = (struct ghw_type_array *)ghw_read_typeid (h); + + sa = ghw_read_array_subtype (h, base); + sa->name = name; h->types[i] = (union ghw_type *)sa; + if (h->flag_verbose > 1) + printf ("subtype array: %s (nbr_scalars=%d)\n", + sa->name, sa->nbr_scalars); } break; case ghdl_rtik_type_record: { struct ghw_type_record *rec; int j; - int nbr_el; + int nbr_scalars; rec = malloc (sizeof (struct ghw_type_record)); rec->kind = t; rec->name = ghw_read_strid (h); if (ghw_read_uleb128 (h, &rec->nbr_fields) != 0) return -1; - rec->el = malloc + rec->els = malloc (rec->nbr_fields * sizeof (struct ghw_record_element)); - nbr_el = 0; + nbr_scalars = 0; for (j = 0; j < rec->nbr_fields; j++) { - rec->el[j].name = ghw_read_strid (h); - rec->el[j].type = ghw_read_typeid (h); - nbr_el += get_nbr_elements (rec->el[j].type); + rec->els[j].name = ghw_read_strid (h); + rec->els[j].type = ghw_read_typeid (h); + if (nbr_scalars != -1) + { + int field_nbr_scalars = get_nbr_elements (rec->els[j].type); + if (field_nbr_scalars == -1) + nbr_scalars = -1; + else + nbr_scalars += field_nbr_scalars; + } } - rec->nbr_el = nbr_el; + rec->nbr_scalars = nbr_scalars; if (h->flag_verbose > 1) - printf ("record type: %s (nbr_el=%d)\n", rec->name, rec->nbr_el); + printf ("record type: %s (nbr_scalars=%d)\n", + rec->name, rec->nbr_scalars); h->types[i] = (union ghw_type *)rec; } break; case ghdl_rtik_subtype_record: { struct ghw_subtype_record *sr; + const char *name; + struct ghw_type_record *base; - sr = malloc (sizeof (struct ghw_subtype_record)); - sr->kind = t; - sr->name = ghw_read_strid (h); - sr->base = (struct ghw_type_record *)ghw_read_typeid (h); - if (h->flag_verbose > 1) - printf ("subtype record: %s\n", sr->name); + name = ghw_read_strid (h); + base = (struct ghw_type_record *)ghw_read_typeid (h); + + sr = ghw_read_record_subtype (h, base); + sr->name = name; h->types[i] = (union ghw_type *)sr; + if (h->flag_verbose > 1) + printf ("subtype record: %s (nbr_scalars=%d)\n", + sr->name, sr->nbr_scalars); } break; default: @@ -710,13 +802,12 @@ ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t) } return 0; case ghdl_rtik_subtype_array: - case ghdl_rtik_subtype_array_ptr: { int i; int stride; int len; - len = t->sa.nbr_el; + len = t->sa.nbr_scalars; stride = get_nbr_elements (t->sa.base->el); for (i = 0; i < len; i += stride) @@ -726,20 +817,36 @@ ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t) return 0; case ghdl_rtik_type_record: { + struct ghw_type_record *r = &t->rec; + int nbr_fields = r->nbr_fields; int i; int off; off = 0; - for (i = 0; i < t->rec.nbr_fields; i++) + for (i = 0; i < nbr_fields; i++) { - if (ghw_read_signal (h, &sigs[off], t->rec.el[i].type) < 0) + if (ghw_read_signal (h, &sigs[off], r->els[i].type) < 0) return -1; - off += get_nbr_elements (t->rec.el[i].type); + off += get_nbr_elements (r->els[i].type); } } return 0; case ghdl_rtik_subtype_record: - return ghw_read_signal (h, sigs, (union ghw_type *)t->sr.base); + { + struct ghw_subtype_record *sr = &t->sr; + int nbr_fields = sr->base->nbr_fields; + int i; + int off; + + off = 0; + for (i = 0; i < nbr_fields; i++) + { + if (ghw_read_signal (h, &sigs[off], sr->els[i].type) < 0) + return -1; + off += get_nbr_elements (sr->els[i].type); + } + } + return 0; default: fprintf (stderr, "ghw_read_signal: type kind %d unhandled\n", t->kind); abort (); @@ -1765,6 +1872,57 @@ ghw_disp_range (union ghw_type *type, union ghw_range *rng) } static void +ghw_disp_array_subtype_bounds (struct ghw_subtype_array *a) +{ + int i; + + printf (" ("); + for (i = 0; i < a->base->nbr_dim; i++) + { + if (i != 0) + printf (", "); + ghw_disp_range (a->base->dims[i], a->rngs[i]); + } + printf (")"); +} + +static void +ghw_disp_record_subtype_bounds (struct ghw_subtype_record *sr) +{ + struct ghw_type_record *base = sr->base; + int is_first = 1; + int i; + + for (i = 0; i < base->nbr_fields; i++) + { + if (sr->els[i].type != base->els[i].type) + { + if (is_first) + { + printf ("("); + is_first = 0; + } + else + printf (", "); + printf ("%s", base->els[i].name); + switch (sr->els[i].type->kind) + { + case ghdl_rtik_subtype_array: + ghw_disp_array_subtype_bounds (&sr->els[i].type->sa); + break; + case ghdl_rtik_subtype_record: + ghw_disp_record_subtype_bounds (&sr->els[i].type->sr); + break; + default: + printf ("??? (%d)", sr->els[i].type->kind); + } + } + } + if (!is_first) + printf (")"); +} + +static void ghw_disp_subtype_definition (struct ghw_handler *h, union ghw_type *t) { switch (t->kind) @@ -1778,24 +1936,20 @@ ghw_disp_subtype_definition (struct ghw_handler *h, union ghw_type *t) } break; case ghdl_rtik_subtype_array: - case ghdl_rtik_subtype_array_ptr: { struct ghw_subtype_array *a = &t->sa; - int i; ghw_disp_typename (h, (union ghw_type *)a->base); - printf (" ("); - for (i = 0; i < a->base->nbr_dim; i++) - { - if (i != 0) - printf (", "); - ghw_disp_range (a->base->dims[i], a->rngs[i]); - } - printf (")"); + ghw_disp_array_subtype_bounds (a); } break; case ghdl_rtik_subtype_record: - ghw_disp_typename (h, (union ghw_type *)t->sr.base); + { + struct ghw_subtype_record *sr = &t->sr; + + ghw_disp_typename (h, (union ghw_type *)sr->base); + ghw_disp_record_subtype_bounds (sr); + } break; default: printf ("ghw_disp_subtype_definition: unhandled type kind %d\n", @@ -1893,15 +2047,14 @@ ghw_disp_type (struct ghw_handler *h, union ghw_type *t) printf ("type %s is record\n", r->name); for (i = 0; i < r->nbr_fields; i++) { - printf (" %s: ", r->el[i].name); - ghw_disp_subtype_indication (h, r->el[i].type); + printf (" %s: ", r->els[i].name); + ghw_disp_subtype_indication (h, r->els[i].type); printf (";\n"); } printf ("end record;\n"); } break; case ghdl_rtik_subtype_array: - case ghdl_rtik_subtype_array_ptr: case ghdl_rtik_subtype_scalar: case ghdl_rtik_subtype_record: { |