1 //
2 //  Copyright (C) 2013-2018  Nick Gasson
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 //
17 
18 #define COMMON_IMPL
19 
20 #include "util.h"
21 #include "common.h"
22 #include "phase.h"
23 
24 #include <assert.h>
25 #include <ctype.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <inttypes.h>
29 
30 static vhdl_standard_t current_std = STD_93;
31 static int relax = 0;
32 
assume_int(tree_t t)33 int64_t assume_int(tree_t t)
34 {
35    switch (tree_kind(t)) {
36    case T_LITERAL:
37       assert(tree_subkind(t) == L_INT);
38       return tree_ival(t);
39 
40    case T_REF:
41       {
42          tree_t ref = tree_ref(t);
43          if (tree_kind(ref) == T_CONST_DECL)
44             return assume_int(tree_value(ref));
45          else {
46             assert(tree_kind(ref) == T_ENUM_LIT);
47             return tree_pos(ref);
48          }
49       }
50 
51    case T_TYPE_CONV:
52    case T_QUALIFIED:
53    case T_FCALL:
54       {
55          const eval_flags_t flags =
56             EVAL_FCALL | EVAL_BOUNDS | EVAL_WARN | EVAL_REPORT | EVAL_LOWER;
57          tree_t new = eval(t, flags);
58          const tree_kind_t new_kind = tree_kind(new);
59          switch (new_kind) {
60          case T_LITERAL:
61          case T_REF:
62          case T_TYPE_CONV:
63          case T_QUALIFIED:
64             return assume_int(new);
65          default:
66             break;
67          }
68       }
69       // Fall-through
70 
71    default:
72       fatal_at(tree_loc(t), "expression cannot be folded to "
73                "an integer constant");
74    }
75 }
76 
range_bounds(range_t r,int64_t * low,int64_t * high)77 void range_bounds(range_t r, int64_t *low, int64_t *high)
78 {
79    const int64_t left = assume_int(r.left);
80    const int64_t right = assume_int(r.right);
81 
82    *low  = r.kind == RANGE_TO ? left : right;
83    *high = r.kind == RANGE_TO ? right : left;
84 }
85 
call_builtin(const char * builtin,type_t type,...)86 tree_t call_builtin(const char *builtin, type_t type, ...)
87 {
88    struct decl_cache {
89       struct decl_cache *next;
90       ident_t bname;
91       tree_t  decl;
92    };
93 
94    char *name = xasprintf("NVC.BUILTIN.%s", builtin);
95    for (char *p = name; *p != '\0'; p++)
96       *p = toupper((int)*p);
97 
98    static struct decl_cache *cache = NULL;
99 
100    ident_t bname = ident_new(builtin);
101    ident_t name_i = ident_new(name);
102    free(name);
103 
104    struct decl_cache *it;
105    tree_t decl = NULL;
106    for (it = cache; it != NULL; it = it->next) {
107       if (it->bname == bname) {
108          decl = it->decl;
109          break;
110       }
111    }
112 
113    if (decl == NULL) {
114       decl = tree_new(T_FUNC_DECL);
115       tree_set_ident(decl, name_i);
116       tree_add_attr_str(decl, builtin_i, ident_new(builtin));
117    }
118 
119    struct decl_cache *c = xmalloc(sizeof(struct decl_cache));
120    c->next  = cache;
121    c->bname = bname;
122    c->decl  = decl;
123 
124    cache = c;
125 
126    tree_t call = tree_new(T_FCALL);
127    tree_set_ident(call, name_i);
128    tree_set_ref(call, decl);
129    if (type != NULL)
130       tree_set_type(call, type);
131 
132    va_list ap;
133    va_start(ap, type);
134    tree_t arg;
135    while ((arg = va_arg(ap, tree_t))) {
136       tree_t p = tree_new(T_PARAM);
137       tree_set_value(p, arg);
138       tree_set_loc(p, tree_loc(arg));
139       tree_set_subkind(p, P_POS);
140 
141       tree_add_param(call, p);
142    }
143    va_end(ap);
144 
145    return call;
146 }
147 
folded_int(tree_t t,int64_t * l)148 bool folded_int(tree_t t, int64_t *l)
149 {
150    switch (tree_kind(t)) {
151    case T_LITERAL:
152       if (tree_subkind(t) == L_INT) {
153          *l = tree_ival(t);
154          return true;
155       }
156       else
157          return false;
158    case T_QUALIFIED:
159       return folded_int(tree_value(t), l);
160    default:
161       return false;
162    }
163 }
164 
folded_real(tree_t t,double * l)165 bool folded_real(tree_t t, double *l)
166 {
167    switch (tree_kind(t)) {
168    case T_LITERAL:
169       if (tree_subkind(t) == L_REAL) {
170          *l = tree_dval(t);
171          return true;
172       }
173       else
174          return false;
175    case T_QUALIFIED:
176       return folded_real(tree_value(t), l);
177    default:
178       return false;
179    }
180 }
181 
folded_length(range_t r,int64_t * l)182 bool folded_length(range_t r, int64_t *l)
183 {
184    int64_t low, high;
185    if (folded_bounds(r, &low, &high)) {
186       *l = MAX(high - low + 1, 0);
187       return true;
188    }
189    else
190       return false;
191 }
192 
folded_bounds(range_t r,int64_t * low,int64_t * high)193 bool folded_bounds(range_t r, int64_t *low, int64_t *high)
194 {
195    int64_t left, right;
196    unsigned leftu, rightu;
197    if (folded_int(r.left, &left) && folded_int(r.right, &right))
198        ;
199    else if (folded_enum(r.left, &leftu) && folded_enum(r.right, &rightu)) {
200       left  = leftu;
201       right = rightu;
202    }
203    else
204       return false;
205 
206    switch (r.kind) {
207    case RANGE_TO:
208       *low  = left;
209       *high = right;
210       return true;
211    case RANGE_DOWNTO:
212       *low  = right;
213       *high = left;
214       return true;
215    default:
216       return false;
217    }
218 }
219 
folded_bounds_real(range_t r,double * low,double * high)220 bool folded_bounds_real(range_t r, double *low, double *high)
221 {
222    double left, right;
223    if (folded_real(r.left, &left) && folded_real(r.right, &right)) {
224       switch (r.kind) {
225       case RANGE_TO:
226          *low  = left;
227          *high = right;
228          return true;
229       case RANGE_DOWNTO:
230          *low  = right;
231          *high = left;
232          return true;
233       default:
234          return false;
235       }
236    }
237    else
238       return false;
239 }
240 
folded_enum(tree_t t,unsigned * pos)241 bool folded_enum(tree_t t, unsigned *pos)
242 {
243    if (tree_kind(t) == T_REF) {
244       tree_t decl = tree_ref(t);
245       if (tree_kind(decl) == T_ENUM_LIT) {
246          *pos = tree_pos(decl);
247          return true;
248       }
249    }
250 
251    return false;
252 }
253 
folded_bool(tree_t t,bool * b)254 bool folded_bool(tree_t t, bool *b)
255 {
256    if (tree_kind(t) == T_REF) {
257       tree_t decl = tree_ref(t);
258       if (tree_kind(decl) == T_ENUM_LIT
259           && type_ident(tree_type(decl)) == std_bool_i) {
260          *b = (tree_pos(decl) == 1);
261          return true;
262       }
263    }
264 
265    return false;
266 }
267 
get_enum_lit(tree_t t,int pos)268 tree_t get_enum_lit(tree_t t, int pos)
269 {
270    type_t enum_type = type_base_recur(tree_type(t));
271    tree_t lit = type_enum_literal(enum_type, pos);
272 
273    tree_t b = tree_new(T_REF);
274    tree_set_loc(b, tree_loc(t));
275    tree_set_ref(b, lit);
276    tree_set_type(b, enum_type);
277    tree_set_ident(b, tree_ident(lit));
278 
279    return b;
280 }
281 
get_int_lit(tree_t t,int64_t i)282 tree_t get_int_lit(tree_t t, int64_t i)
283 {
284    tree_t f = tree_new(T_LITERAL);
285    tree_set_subkind(f, L_INT);
286    tree_set_ival(f, i);
287    tree_set_loc(f, tree_loc(t));
288    tree_set_type(f, tree_type(t));
289 
290    return f;
291 }
292 
get_real_lit(tree_t t,double r)293 tree_t get_real_lit(tree_t t, double r)
294 {
295    tree_t f = tree_new(T_LITERAL);
296    tree_set_loc(f, tree_loc(t));
297    tree_set_subkind(f, L_REAL);
298    tree_set_dval(f, r);
299    tree_set_type(f, tree_type(t));
300 
301    return f;
302 }
303 
package_signal_path_name(ident_t i)304 const char *package_signal_path_name(ident_t i)
305 {
306    const char *str = istr(i);
307    if (str[0] == ':')
308       return str;
309 
310    char *buf = get_fmt_buf(strlen(str) + 3);
311    char *p = buf;
312 
313    *p++ = ':';
314    while (*str != '\0') {
315       if (*str == '.') {
316          *p++ = ':';
317          str++;
318       }
319       else {
320          *p++ = tolower((int)*str);
321          str++;
322       }
323    }
324    *p = '\0';
325 
326    return buf;
327 }
328 
parse_value(type_t type,const char * str,int64_t * value)329 bool parse_value(type_t type, const char *str, int64_t *value)
330 {
331    while (isspace((int)*str))
332       ++str;
333 
334    type_t base = type_base_recur(type);
335 
336    switch (type_kind(base)) {
337    case T_INTEGER:
338       {
339          bool is_negative = *str == '-';
340          int num_digits = 0;
341 
342          if (is_negative) {
343             ++str;
344          }
345          int64_t sum = 0;
346          while (isdigit((int)*str) || (*str == '_')) {
347             if (*str != '_') {
348                sum *= 10;
349                sum += (*str - '0');
350                num_digits++;
351             }
352             ++str;
353          }
354 
355          if (is_negative) {
356             *value = -sum;
357          }
358          else {
359             *value = sum;
360          }
361 
362          if (num_digits == 0) {
363             return false;
364          }
365       }
366       break;
367 
368    case T_ENUM:
369       {
370          bool upcase = true;
371          char *copy LOCAL = xstrdup(str), *p;
372          for (p = copy; (*p != '\0') && !isspace((int)*p); p++, str++) {
373             if (*p == '\'')
374                upcase = false;
375             if (upcase)
376                *p = toupper((int)*p);
377          }
378          *p = '\0';
379 
380          ident_t id = ident_new(copy);
381 
382          *value = -1;
383 
384          const int nlits = type_enum_literals(base);
385          for (int i = 0; (*value == -1) && (i < nlits); i++) {
386             if (tree_ident(type_enum_literal(base, i)) == id)
387                *value = i;
388          }
389 
390          if (*value == -1)
391             return false;
392       }
393       break;
394 
395    default:
396       break;
397    }
398 
399    while (*str != '\0') {
400       if (!isspace((int)*str)) {
401          str++;
402          return false;
403       }
404       else {
405          str++;
406       }
407    }
408 
409    return true;
410 }
411 
make_ref(tree_t to)412 tree_t make_ref(tree_t to)
413 {
414    tree_t t = tree_new(T_REF);
415    tree_set_ident(t, tree_ident(to));
416    tree_set_ref(t, to);
417    tree_set_type(t, tree_type(to));
418    return t;
419 }
420 
standard(void)421 vhdl_standard_t standard(void)
422 {
423    return current_std;
424 }
425 
set_standard(vhdl_standard_t s)426 void set_standard(vhdl_standard_t s)
427 {
428    current_std = s;
429 }
430 
standard_text(vhdl_standard_t s)431 const char *standard_text(vhdl_standard_t s)
432 {
433    static const char *text[] = {
434       "1987", "1993", "2000", "2002", "2008"
435    };
436 
437    if ((unsigned)s < ARRAY_LEN(text))
438       return text[s];
439    else
440       return "????";
441 }
442 
record_field_to_net(type_t type,ident_t name)443 int record_field_to_net(type_t type, ident_t name)
444 {
445    int offset = 0;
446 
447    const int nfields = type_fields(type);
448    for (int i = 0; i < nfields; i++) {
449       tree_t field = type_field(type, i);
450       if (tree_ident(field) == name)
451          return offset;
452       else
453          offset += type_width(tree_type(field));
454    }
455 
456    assert(false);
457 }
458 
find_record_field(tree_t rref)459 tree_t find_record_field(tree_t rref)
460 {
461    ident_t fname = tree_ident(rref);
462    type_t value_type = tree_type(tree_value(rref));
463 
464    const int nfields = type_fields(value_type);
465    for (int i = 0; i < nfields; i++) {
466       tree_t field = type_field(value_type, i);
467       if (tree_ident(field) == fname)
468          return field;
469    }
470 
471    return NULL;
472 }
473 
class_of(tree_t t)474 class_t class_of(tree_t t)
475 {
476    switch (tree_kind(t)) {
477    case T_VAR_DECL:
478       return C_VARIABLE;
479    case T_SIGNAL_DECL:
480       return C_SIGNAL;
481    case T_CONST_DECL:
482       return C_CONSTANT;
483    case T_PORT_DECL:
484       return tree_class(t);
485    case T_ENUM_LIT:
486    case T_LITERAL:
487       return C_LITERAL;
488    case T_GENVAR:
489    case T_ALIAS:
490    case T_FIELD_DECL:
491       return C_DEFAULT;
492    case T_UNIT_DECL:
493       return C_UNITS;
494    case T_ARCH:
495       return C_ARCHITECTURE;
496    case T_FUNC_DECL:
497    case T_FUNC_BODY:
498       return C_FUNCTION;
499    case T_PROC_DECL:
500    case T_PROC_BODY:
501       return C_PROCEDURE;
502    case T_ENTITY:
503       return C_ENTITY;
504    case T_TYPE_DECL:
505       return C_TYPE;
506    case T_FILE_DECL:
507       return C_FILE;
508    case T_PROCESS:
509    case T_BLOCK:
510    case T_FOR:
511       return C_LABEL;
512    case T_COMPONENT:
513       return C_COMPONENT;
514    case T_REF:
515       return class_of(tree_ref(t));
516    case T_ARRAY_REF:
517    case T_ARRAY_SLICE:
518    case T_RECORD_REF:
519       return class_of(tree_value(t));
520    case T_PACKAGE:
521       return C_PACKAGE;
522    case T_LIBRARY:
523       return C_LIBRARY;
524    case T_ELAB:
525       return C_ELAB;
526    default:
527       fatal("missing class_of for %s", tree_kind_str(tree_kind(t)));
528    }
529 }
530 
class_has_type(class_t c)531 bool class_has_type(class_t c)
532 {
533    switch (c) {
534    case C_LABEL:
535    case C_ENTITY:
536    case C_ARCHITECTURE:
537    case C_COMPONENT:
538    case C_CONFIGURATION:
539    case C_PACKAGE:
540    case C_LIBRARY:
541    case C_ELAB:
542       return false;
543    default:
544       return true;
545    }
546 }
547 
class_str(class_t c)548 const char *class_str(class_t c)
549 {
550    static const char *strs[] = {
551       "default", "signal", "variable", "constant", "file", "entity",
552       "component", "configuration", "architecture", "function", "package",
553       "type", "subtype", "label", "procedure", "literal", "units"
554    };
555    assert(c < ARRAY_LEN(strs));
556    return strs[c];
557 }
558 
add_param(tree_t call,tree_t value,param_kind_t kind,tree_t name)559 tree_t add_param(tree_t call, tree_t value, param_kind_t kind, tree_t name)
560 {
561    tree_t p = tree_new(T_PARAM);
562    tree_set_loc(p, tree_loc(value));
563    tree_set_subkind(p, kind);
564    tree_set_value(p, value);
565 
566    if (kind == P_NAMED) {
567       assert(name != NULL);
568       tree_set_name(p, name);
569    }
570 
571    tree_add_param(call, p);
572    return p;
573 }
574 
575 
array_aggregate_type(type_t array,int from_dim)576 type_t array_aggregate_type(type_t array, int from_dim)
577 {
578    if (type_is_unconstrained(array)) {
579       const int nindex = type_index_constrs(array);
580       assert(from_dim < nindex);
581 
582       type_t type = type_new(T_UARRAY);
583       type_set_ident(type, type_ident(array));
584       type_set_elem(type, type_elem(array));
585 
586       for (int i = from_dim; i < nindex; i++)
587          type_add_index_constr(type, type_index_constr(array, i));
588 
589       return type;
590    }
591    else {
592       const int ndims = array_dimension(array);
593       assert(from_dim < ndims);
594 
595       type_t type = type_new(T_CARRAY);
596       type_set_ident(type, type_ident(array));
597       type_set_elem(type, type_elem(array));
598 
599       for (int i = from_dim; i < ndims; i++)
600          type_add_dim(type, range_of(array, i));
601 
602       return type;
603    }
604 }
605 
make_default_value(type_t type,const loc_t * loc)606 tree_t make_default_value(type_t type, const loc_t *loc)
607 {
608    type_t base = type_base_recur(type);
609 
610    switch (type_kind(base)) {
611    case T_UARRAY:
612       assert(type_kind(type) == T_SUBTYPE);
613       // Fall-through
614 
615    case T_CARRAY:
616       {
617          tree_t def = NULL;
618          const int ndims = array_dimension(type);
619          for (int i = ndims - 1; i >= 0; i--) {
620             tree_t val = (def ? def : make_default_value(type_elem(base), loc));
621             def = tree_new(T_AGGREGATE);
622             tree_set_type(def, array_aggregate_type(type, i));
623 
624             tree_t a = tree_new(T_ASSOC);
625             tree_set_subkind(a, A_OTHERS);
626             tree_set_value(a, val);
627 
628             tree_add_assoc(def, a);
629          }
630          tree_set_type(def, type);
631          tree_set_loc(def, loc);
632          return def;
633       }
634 
635    case T_INTEGER:
636    case T_PHYSICAL:
637    case T_REAL:
638       return range_of(type, 0).left;
639 
640    case T_ENUM:
641       {
642          int64_t val = 0;
643          range_t r = range_of(type, 0);
644          const bool folded = folded_int(r.left, &val);
645          if (folded)
646             return make_ref(type_enum_literal(base, (unsigned) val));
647          else
648             return r.left;
649       }
650 
651    case T_RECORD:
652       {
653          tree_t def = tree_new(T_AGGREGATE);
654          tree_set_loc(def, loc);
655          const int nfields = type_fields(base);
656          for (int i = 0; i < nfields; i++) {
657             tree_t field = type_field(base, i);
658 
659             tree_t a = tree_new(T_ASSOC);
660             tree_set_subkind(a, A_POS);
661             tree_set_value(a, make_default_value(tree_type(field),
662                                                  tree_loc(field)));
663 
664             tree_add_assoc(def, a);
665          }
666          tree_set_type(def, type);
667          return def;
668       }
669 
670    case T_ACCESS:
671       {
672          tree_t null = tree_new(T_LITERAL);
673          tree_set_loc(null, loc);
674          tree_set_subkind(null, L_NULL);
675          tree_set_type(null, type);
676          return null;
677       }
678 
679    case T_UNRESOLVED:
680       return NULL;
681 
682    default:
683       fatal_trace("cannot handle type %s in %s",
684                   type_kind_str(type_kind(base)), __func__);
685    }
686 }
687 
fmt_time_r(char * buf,size_t len,uint64_t t)688 const char *fmt_time_r(char *buf, size_t len, uint64_t t)
689 {
690    static const struct {
691       uint64_t time;
692       const char *unit;
693    } units[] = {
694       { UINT64_C(1), "fs" },
695       { UINT64_C(1000), "ps" },
696       { UINT64_C(1000000), "ns" },
697       { UINT64_C(1000000000), "us" },
698       { UINT64_C(1000000000000), "ms" },
699       { 0, NULL }
700    };
701 
702    int u = 0;
703    while (units[u + 1].unit && (t % units[u + 1].time == 0))
704       ++u;
705 
706    snprintf(buf, len, "%"PRIu64"%s",
707             t / units[u].time, units[u].unit);
708 
709    return buf;
710 }
711 
fmt_time(uint64_t t)712 const char *fmt_time(uint64_t t)
713 {
714    static const int BUF_SZ = 64;
715    return fmt_time_r(get_fmt_buf(BUF_SZ), BUF_SZ, t);
716 }
717 
bits_for_range(int64_t low,int64_t high)718 unsigned bits_for_range(int64_t low, int64_t high)
719 {
720    assert(low <= high);
721 
722    if (low < 0) {
723       // Signed integers
724       if (low >= INT8_MIN && high <= INT8_MAX)
725          return 8;
726       else if (low >= INT16_MIN && high <= INT16_MAX)
727          return 16;
728       else if (low >= INT32_MIN && high <= INT32_MAX)
729          return 32;
730       else
731          return 64;
732    }
733    else {
734       // Unsigned integers
735       if (high <= 1)
736          return 1;
737       else if (high <= UINT8_MAX)
738          return 8;
739       else if (high <= UINT16_MAX)
740          return 16;
741       else if (high <= UINT32_MAX)
742          return 32;
743       else
744          return 64;
745    }
746 }
747 
array_dimension(type_t a)748 unsigned array_dimension(type_t a)
749 {
750    switch (type_kind(a)) {
751    case T_SUBTYPE:
752       if (type_has_constraint(a))
753          return tree_ranges(type_constraint(a));
754       else
755          return array_dimension(type_base(a));
756    case T_CARRAY:
757       return type_dims(a);
758    case T_UARRAY:
759       return type_index_constrs(a);
760    default:
761       fatal_trace("non-array type %s in array_dimension",
762                   type_kind_str(type_kind(a)));
763    }
764 }
765 
range_of(type_t type,unsigned dim)766 range_t range_of(type_t type, unsigned dim)
767 {
768    switch (type_kind(type)) {
769    case T_SUBTYPE:
770       if (type_has_constraint(type))
771          return tree_range(type_constraint(type), dim);
772       else
773          return range_of(type_base(type), dim);
774    case T_INTEGER:
775    case T_REAL:
776    case T_PHYSICAL:
777    case T_CARRAY:
778    case T_ENUM:
779       return type_dim(type, dim);
780    default:
781       fatal_trace("invalid type kind %s in range_of",
782                   type_kind_str(type_kind(type)));
783    }
784 }
785 
direction_of(type_t type,unsigned dim)786 range_kind_t direction_of(type_t type, unsigned dim)
787 {
788    switch (type_kind(type)) {
789    case T_ENUM:
790       return RANGE_TO;
791    case T_INTEGER:
792    case T_REAL:
793    case T_PHYSICAL:
794    case T_CARRAY:
795    case T_SUBTYPE:
796       return range_of(type, dim).kind;
797    default:
798       fatal_trace("invalid type kind %s in direction_of",
799                   type_kind_str(type_kind(type)));
800    }
801 }
802 
index_type_of(type_t type,int dim)803 type_t index_type_of(type_t type, int dim)
804 {
805    if (type_is_unconstrained(type))
806       return type_index_constr(type_base_recur(type), dim);
807    else if (type_kind(type) == T_ENUM)
808       return type;
809    else {
810       tree_t left = range_of(type, dim).left;
811 
812       // If the left bound has not been assigned a type then there is some
813       // error with it so just return a dummy type here
814       return tree_has_type(left) ? tree_type(left) : type_new(T_NONE);
815    }
816 }
817 
rebase_index(type_t array_type,int dim,int64_t value)818 int64_t rebase_index(type_t array_type, int dim, int64_t value)
819 {
820    // Convert value which is in the range of array_type to a zero-based index
821    range_t r = range_of(array_type, dim);
822    const int64_t left = assume_int(r.left);
823    return (r.kind == RANGE_TO) ? value - left : left - value;
824 }
825 
str_to_literal(const char * start,const char * end,type_t type)826 tree_t str_to_literal(const char *start, const char *end, type_t type)
827 {
828    tree_t t = tree_new(T_LITERAL);
829    tree_set_subkind(t, L_STRING);
830 
831    type_t elem = NULL;
832    if (type != NULL) {
833       tree_set_type(t, type);
834       elem = type_elem(type);
835    }
836 
837    for (const char *p = start; *p != '\0' && p != end; p++) {
838       if (*(const unsigned char *)p == 0x81)
839          continue;   // Allow UTF-8 encoded ASCII characters
840 
841       const char ch[] = { '\'', *p, '\'', '\0' };
842       ident_t id = ident_new(ch);
843       tree_t ref = tree_new(T_REF);
844       tree_set_ident(ref, id);
845       tree_add_char(t, ref);
846 
847       if (elem != NULL) {
848          const int nlit = type_enum_literals(elem);
849          for (int i = 0; i < nlit; i++) {
850             tree_t lit = type_enum_literal(elem, i);
851             if (tree_ident(lit) == id) {
852                tree_set_ref(ref, lit);
853                break;
854             }
855          }
856       }
857    }
858 
859    return t;
860 }
861 
loc_eq(const loc_t * a,const loc_t * b)862 bool loc_eq(const loc_t *a, const loc_t *b)
863 {
864    return a->first_line == b->first_line
865       && a->first_column == b->first_column
866       && a->last_line == b->last_line
867       && a->last_column == b->last_column
868       && a->file == b->file;
869 }
870 
loc_write(const loc_t * loc,fbuf_t * f,ident_wr_ctx_t ctx)871 void loc_write(const loc_t *loc, fbuf_t *f, ident_wr_ctx_t ctx)
872 {
873    ident_write(loc->file, ctx);
874 
875    const uint64_t merged =
876       ((uint64_t)loc->first_line << 44)
877       | ((uint64_t)loc->first_column << 32)
878       | ((uint64_t)loc->last_line << 12)
879       | (uint64_t)loc->last_column;
880 
881    write_u64(merged, f);
882 }
883 
loc_read(loc_t * loc,fbuf_t * f,ident_rd_ctx_t ctx)884 void loc_read(loc_t *loc, fbuf_t *f, ident_rd_ctx_t ctx)
885 {
886    loc->file = ident_read(ctx);
887    loc->linebuf = NULL;
888 
889    const uint64_t merged = read_u64(f);
890 
891    loc->first_line   = (merged >> 44) & 0xfffff;
892    loc->first_column = (merged >> 32) & 0xfff;
893    loc->last_line    = (merged >> 12) & 0xfffff;
894    loc->last_column  = merged & 0xfff;
895 }
896 
vcode_file_name(ident_t unit_name)897 char *vcode_file_name(ident_t unit_name)
898 {
899    return xasprintf("_%s.vcode", istr(unit_name));
900 }
901 
intern_strings(void)902 void intern_strings(void)
903 {
904    builtin_i        = ident_new("builtin");
905    std_standard_i   = ident_new("STD.STANDARD");
906    formal_i         = ident_new("formal");
907    elab_copy_i      = ident_new("elab_copy");
908    all_i            = ident_new("all");
909    protected_i      = ident_new("protected");
910    inst_name_i      = ident_new("INSTANCE_NAME");
911    fst_dir_i        = ident_new("fst_dir");
912    scope_pop_i      = ident_new("scope_pop");
913    partial_map_i    = ident_new("partial_map");
914    fst_data_i       = ident_new("fst_data");
915    std_logic_i      = ident_new("IEEE.STD_LOGIC_1164.STD_LOGIC");
916    std_ulogic_i     = ident_new("IEEE.STD_LOGIC_1164.STD_ULOGIC");
917    std_bit_i        = ident_new("STD.STANDARD.BIT");
918    std_bool_i       = ident_new("STD.STANDARD.BOOLEAN");
919    std_char_i       = ident_new("STD.STANDARD.CHARACTER");
920    natural_i        = ident_new("STD.STANDARD.NATURAL");
921    positive_i       = ident_new("STD.STANDARD.POSITIVE");
922    signed_i         = ident_new("IEEE.NUMERIC_STD.SIGNED");
923    unsigned_i       = ident_new("IEEE.NUMERIC_STD.UNSIGNED");
924    foreign_i        = ident_new("FOREIGN");
925    nested_i         = ident_new("nested");
926    drives_all_i     = ident_new("drives_all");
927    driver_init_i    = ident_new("driver_init");
928    static_i         = ident_new("static");
929    mangled_i        = ident_new("mangled");
930    null_range_i     = ident_new("null_range");
931    deferred_i       = ident_new("deferred");
932    prot_field_i     = ident_new("prot_field");
933    stmt_tag_i       = ident_new("stmt_tag");
934    cond_tag_i       = ident_new("cond_tag");
935    sub_cond_i       = ident_new("sub_cond");
936    range_var_i      = ident_new("range_var");
937    work_i           = ident_new("WORK");
938    wait_level_i     = ident_new("wait_level");
939    impure_io_i      = ident_new("impure_io");
940    simple_name_i    = ident_new("simple_name");
941    std_i            = ident_new("STD");
942    nnets_i          = ident_new("nnets");
943    thunk_i          = ident_new("thunk");
944 }
945 
pack_needs_cgen(tree_t t)946 bool pack_needs_cgen(tree_t t)
947 {
948    // True if the package contains shared variables or signals which
949    // must be run through code generation
950 
951    const int ndecls = tree_decls(t);
952    for (int i = 0; i < ndecls; i++) {
953       tree_t decl = tree_decl(t, i);
954       switch (tree_kind(decl)) {
955       case T_VAR_DECL:
956       case T_SIGNAL_DECL:
957       case T_FILE_DECL:
958          return true;
959       case T_CONST_DECL:
960          if (type_is_array(tree_type(decl)))
961             return true;
962          else if (tree_has_value(decl)) {
963             if (tree_kind(tree_value(decl)) != T_LITERAL)
964                return true;
965          }
966          break;
967       default:
968          break;
969       }
970    }
971 
972    return false;
973 }
974 
mangle_one_type(text_buf_t * buf,type_t type)975 static void mangle_one_type(text_buf_t *buf, type_t type)
976 {
977    ident_t ident = type_ident(type);
978 
979    if (icmp(ident, "STD.STANDARD.INTEGER"))
980       tb_printf(buf, "I");
981    else if (icmp(ident, "STD.STANDARD.STRING"))
982       tb_printf(buf, "S");
983    else if (icmp(ident, "STD.STANDARD.REAL"))
984       tb_printf(buf, "R");
985    else if (icmp(ident, "STD.STANDARD.BOOLEAN"))
986       tb_printf(buf, "B");
987    else if (icmp(ident, "STD.STANDARD.CHARACTER"))
988       tb_printf(buf, "C");
989    else if (icmp(ident, "STD.STANDARD.TIME"))
990       tb_printf(buf, "T");
991    else if (icmp(ident, "STD.STANDARD.NATURAL"))
992       tb_printf(buf, "N");
993    else if (icmp(ident, "STD.STANDARD.POSITIVE"))
994       tb_printf(buf, "P");
995    else if (icmp(ident, "STD.STANDARD.BIT"))
996       tb_printf(buf, "J");
997    else if (icmp(ident, "STD.STANDARD.BIT_VECTOR"))
998       tb_printf(buf, "Q");
999    else if (icmp(ident, "IEEE.STD_LOGIC_1164.STD_LOGIC"))
1000       tb_printf(buf, "L");
1001    else if (icmp(ident, "IEEE.STD_LOGIC_1164.STD_ULOGIC"))
1002       tb_printf(buf, "U");
1003    else if (icmp(ident, "IEEE.STD_LOGIC_1164.STD_LOGIC_VECTOR"))
1004       tb_printf(buf, "V");
1005    else {
1006       const char *ident_str = istr(ident);
1007       tb_printf(buf, "%d%s", (int)strlen(ident_str), ident_str);
1008    }
1009 }
1010 
mangle_func(tree_t decl,const char * prefix)1011 ident_t mangle_func(tree_t decl, const char *prefix)
1012 {
1013    ident_t prev = tree_attr_str(decl, mangled_i);
1014    if (prev != NULL)
1015       return prev;
1016 
1017    tree_t foreign = tree_attr_tree(decl, foreign_i);
1018    if (foreign != NULL) {
1019       if (tree_kind(foreign) != T_LITERAL)
1020          fatal_at(tree_loc(decl), "foreign attribute must have string "
1021                   "literal value");
1022 
1023       const int nchars = tree_chars(foreign);
1024       char buf[nchars + 1];
1025       for (int i = 0; i < nchars; i++)
1026          buf[i] = tree_pos(tree_ref(tree_char(foreign, i)));
1027       buf[nchars] = '\0';
1028 
1029       ident_t name = ident_new(buf);
1030       tree_add_attr_str(decl, mangled_i, name);
1031       return name;
1032    }
1033 
1034    LOCAL_TEXT_BUF buf = tb_new();
1035 
1036    if (prefix != NULL)
1037       tb_printf(buf, "%s", prefix);
1038 
1039    tb_printf(buf, "%s", istr(tree_ident(decl)));
1040 
1041    const tree_kind_t kind = tree_kind(decl);
1042    const bool is_func = kind == T_FUNC_BODY || kind == T_FUNC_DECL;
1043    const int nports = tree_ports(decl);
1044    if (nports > 0 || is_func)
1045       tb_printf(buf, "(");
1046 
1047    for (int i = 0; i < nports; i++) {
1048       tree_t p = tree_port(decl, i);
1049       if (tree_class(p) == C_SIGNAL)
1050          tb_printf(buf, "s");
1051       mangle_one_type(buf, tree_type(p));
1052    }
1053 
1054    if (nports > 0 || is_func)
1055       tb_printf(buf, ")");
1056 
1057    if (is_func)
1058       mangle_one_type(buf, type_result(tree_type(decl)));
1059 
1060    return ident_new(tb_get(buf));
1061 }
1062 
relax_rules(void)1063 int relax_rules(void)
1064 {
1065    return relax;
1066 }
1067 
set_relax_rules(int mask)1068 void set_relax_rules(int mask)
1069 {
1070    relax = mask;
1071 }
1072