1 /* Copyright (c) 1991-2007 Pragmatic C Software Corp. */
2 
3 /*
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 2 of the License, or (at your
7    option) any later version.
8 
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation, Inc.,
16    59 Temple Place, Suite 330, Boston, MA, 02111-1307.
17 
18    We are selling our new Verilog compiler that compiles to X86 Linux
19    assembly language.  It is at least two times faster for accurate gate
20    level designs and much faster for procedural designs.  The new
21    commercial compiled Verilog product is called CVC.  For more information
22    on CVC visit our website at www.pragmatic-c.com/cvc.htm or contact
23    Andrew at avanvick@pragmatic-c.com
24 
25  */
26 
27 
28 /*
29  * second source module for statement reading and expressions parsing
30  * tasks in src 3
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <math.h>
37 
38 #ifdef __DBMALLOC__
39 #include "../malloc.h"
40 #endif
41 
42 #include "v.h"
43 #include "cvmacros.h"
44 
45 /* local prototypes */
46 static struct st_t *rd_block(int32, int32);
47 static struct st_t *convert_to_fork(struct st_t *);
48 static int32 rd_lstofsts(int32, struct st_t **, int32, int32);
49 static struct st_t *rd_namblock(int32, int32, int32, int32);
50 static struct st_t *rd_if(void);
51 static struct st_t *rd_case(int32);
52 static struct st_t *rd_loop(int32);
53 static struct st_t *rd_for(void);
54 static struct st_t *rd_cause(void);
55 static struct st_t *rd_disable(void);
56 static struct expr_t *find_bldxpr_tfsy(char *, int32);
57 static struct st_t *rd_wireassign(int32);
58 static struct st_t *rd_wiredeassign(int32);
59 static struct st_t *rd_taske_or_proc_assign(void);
60 static struct st_t *rd_dctrl_st(void);
61 static struct expr_t *rd_delctrl(int32 *, int32 *);
62 static int32 col2_lval(void);
63 static int32 col_dctrl_xmr(void);
64 static int32 col_evctrlexpr(void);
65 static void init_gref(struct gref_t *, char *);
66 static struct expr_t *parse_qcexpr(void);
67 static void xskip_toend(void);
68 static struct expr_t *parse_boolorop(void);
69 static struct expr_t *parse_boolandop(void);
70 static struct expr_t *parse_borop(void);
71 static struct expr_t *parse_bxorop(void);
72 static struct expr_t *parse_bandop(void);
73 static struct expr_t *parse_eqop(void);
74 static struct expr_t *parse_ltgtop(void);
75 static struct expr_t *parse_shop(void);
76 static struct expr_t *parse_addop(void);
77 static struct expr_t *parse_mulop(void);
78 static struct expr_t *parse_unopterm(void);
79 static void skip_3valend(void);
80 static int32 is_unop(word32);
81 static struct expr_t *parse_term(void);
82 static int32 decl_id_inexpr(struct expr_t *, struct expridtab_t *);
83 static struct expr_t *parse_concat(void);
84 static struct expr_t *parse_select(struct expr_t *);
85 static struct expr_t *parse_glbref(struct expr_t *, struct expridtab_t *);
86 static struct expr_t *bld_1cmp_global(struct expr_t *, struct expridtab_t *);
87 static char *alloc_glbndp_tostr(struct expr_t *);
88 static void grow_grtab(void);
89 static struct expr_t *parse_fcall(struct expr_t *, struct expridtab_t *, int32);
90 static int32 chk_decl_func(int32 *, struct expr_t *, struct expridtab_t *);
91 static void cnvt_forw_tfcall_1cmpglb(struct expr_t *, char *, int32, int32);
92 static struct expr_t *parse_evexpr(void);
93 static void grow_exprtab(void);
94 static struct expr_t *my_xndalloc(void);
95 static struct expr_t *alloc_xtnd(int32);
96 static void set2_opempty(struct expr_t *);
97 static char *to_xndnam(char *, int32 xndi);
98 static word32 get_hash(word32 *, word32 *, int32);
99 
100 /* extern prototypes (maybe defined in this module) */
101 extern char *__pv_stralloc(char *);
102 extern char *__my_malloc(int32);
103 extern char *__my_realloc(char *, int32, int32);
104 extern char *__msgexpr_tostr(char *, struct expr_t *);
105 extern char *__prt_vtok(void);
106 extern char *__prt_kywrd_vtok(void);
107 extern struct sy_t *__get_sym_env(char *);
108 extern struct sy_t *__get_sym(char *, struct symtab_t *);
109 extern struct sy_t *__decl_sym(char *, struct symtab_t *);
110 extern struct net_t *__add_net(struct sy_t *);
111 extern char *__to_idnam(struct expr_t *);
112 extern char *__to_sytyp(char *, word32);
113 extern struct st_t *__alloc_stmt(int32);
114 extern char *__get_vkeynam(char *, int32);
115 extern void __find_matchendblk(int32, int32);
116 extern void __find_matchendcase(void);
117 extern int32 __col_caseexpr(void);
118 extern struct exprlst_t *__alloc_xprlst(void);
119 extern struct csitem_t *__alloc_csitem(void);
120 extern char *__to_opname(word32);
121 extern struct paramlst_t *__alloc_pval(void);
122 extern char *__regab_tostr(char *, word32 *, word32 *, int32, int32, int32);
123 extern char *__bld_lineloc(char *, word32, int32);
124 extern struct gref_t *__bld_glbref(struct expr_t *, int32, int32);
125 extern struct expr_t *__alloc_newxnd(void);
126 extern void __get_vtok(void);
127 extern void __unget_vtok(void);
128 extern int32 __vskipto_any(int32);
129 extern int32 __vskipto2_any(int32, int32);
130 extern int32 __vskipto3_any(int32, int32, int32);
131 extern int32 __vskipto4_any(int32, int32, int32, int32);
132 extern int32 __bld_tsk(char *, int32);
133 extern int32 __rd_tfdecls(char *);
134 extern void __set_xtab_errval(void);
135 extern void __bld_xtree(int32);
136 extern void __bld_evxtree(void);
137 extern int32 __col_parenexpr(int32);
138 extern int32 __col_lval(void);
139 extern int32 __col_comsemi(int32);
140 extern void __resolve_glbnam(struct gref_t *);
141 extern void __fill_grp_targu_fld(struct gref_t *);
142 extern void __set_opempty(int32);
143 extern int32 __col_connexpr(int32);
144 extern int32 __bld_expnode(void);
145 extern void __init_xnd(struct expr_t *);
146 extern void __set_numval(struct expr_t *, word32, word32, int32);
147 extern void __my_free(char *, int32);
148 extern void __free2_xtree(struct expr_t *);
149 extern struct st_t *__rd_tskenable(char *, struct expr_t *, int32);
150 extern void __setup_contab(void);
151 extern int32 __alloc_shareable_cval(word32, word32, int32);
152 extern int32 __alloc_shareable_rlcval(double);
153 extern int32 __alloc_is_cval(int32);
154 extern int32 __allocfill_cval_new(word32 *, word32 *, int32);
155 extern char *__alloc_vval_to_cstr(word32 *, int32, int32, int32);
156 extern void __grow_contab(int32);
157 extern struct expridtab_t *__alloc_expridnd(char *);
158 extern struct expr_t *__alloc_exprnd(void);
159 
160 extern void __pv_ferr(int32, char *, ...);
161 extern void __pv_fwarn(int32, char *, ...);
162 extern void __gferr(int32, word32, int32, char *, ...);
163 extern void __dbg_msg(char *, ...);
164 extern void __my_fprintf(FILE *, char *, ...);
165 extern void __fterr(int32, char *, ...);
166 extern void __arg_terr(char *, int32);
167 extern void __case_terr(char *, int32);
168 extern void __misc_terr(char *, int32);
169 extern void __misc_fterr(char *, int32);
170 extern void __ia_err(int32 id_num, char *s, ...);
171 
172 extern struct opinfo_t __opinfo[];
173 extern word32 __masktab[];
174 
175 /*
176  * STATEMENT PROCESSING ROUTINES
177  */
178 
179 /*
180  * read statement
181  * expects 1st token read and reads ending ; or end or del. ctrl.
182  * statement routines allocate and return statement - caller links it in
183  *
184  * this routine cannot skip, but if it calls rd_stmt must handle skipping
185  */
__rd_stmt(void)186 extern struct st_t *__rd_stmt(void)
187 {
188  struct st_t *stp;
189 
190  __saverr_cnt = __pv_err_cnt;
191  stp = NULL;
192  /* statement routines for bracketed statements will have skipped to end */
193  switch ((byte) __toktyp) {
194   case IF:
195    if ((stp = rd_if()) == NULL) return(NULL);
196    break;
197   case Begin:
198    /* will have skipped to block end on error */
199    /* if possible this returns list of statements instead of block */
200    if ((stp = rd_block(Begin, END)) == NULL) return(NULL);
201    break;
202   case FORK:
203    if ((stp = rd_block(FORK, JOIN)) == NULL) return(NULL);
204    break;
205   case SEMI:
206    stp = __alloc_stmt(S_NULL);
207    break;
208   case CASE: case CASEX: case CASEZ:
209    if ((stp = rd_case(__toktyp)) == NULL) return(NULL);
210    break;
211   case FOREVER: case WHILE: case WAIT: case REPEAT:
212    /* notice no repeat form del ctrls since repeat keyword indicates stmt */
213    if ((stp = rd_loop(__toktyp)) == NULL) return(NULL);
214    break;
215   case FOR:
216    if ((stp = rd_for()) == NULL) return(NULL);
217    break;
218   case SHARP: case AT:
219    if ((stp = rd_dctrl_st()) == NULL) return(NULL);
220    break;
221   case DISABLE:
222    if ((stp = rd_disable()) == NULL) return(NULL);
223    break;
224   case CAUSE:
225    if ((stp = rd_cause()) == NULL) return(NULL);
226    break;
227   case ASSIGN:
228    if ((stp = rd_wireassign(ASSIGN)) == NULL) return(NULL);
229    break;
230   case DEASSIGN:
231    if ((stp = rd_wiredeassign(DEASSIGN)) == NULL) return(NULL);
232    break;
233   case FORCE:
234    if ((stp = rd_wireassign(FORCE)) == NULL) return(NULL);
235    break;
236   case RELEASE:
237    if ((stp = rd_wiredeassign(RELEASE)) == NULL) return(NULL);
238    break;
239   /* these are resync error conditions - must handle out of sync to end */
240   case ENDTASK:
241   case ENDFUNCTION:
242   case ENDSPECIFY:
243    __pv_ferr(1060, "module item end bracket problem - %s read",
244     __prt_vtok());
245    /* SJM 01/18/1999 - must stay at module level end to try to finish */
246    /* item gracefully */
247    /* ??? __get_vtok(); */
248    __syncto_class = SYNC_MODLEVEL;
249    return(NULL);
250   case ENDCASE:
251   case END:
252   case JOIN:
253    __syncto_class = SYNC_STMT;
254 bad_struct:
255    __pv_ferr(1061, "statement structure end bracket problem - %s read",
256     __prt_vtok());
257    __get_vtok();
258    return(NULL);
259   case ENDMODULE:
260   case ENDPRIMITIVE:
261   case ENDTABLE:
262    __syncto_class = SYNC_FLEVEL;
263    goto bad_struct;
264 
265   /* non keyword - only 2 possibilities */
266   case ID: case LCB:
267    /* exactly 2 things can start proc lhs [id (glb ref)] = , {...} = */
268    /* also task enable [id (glb ref)](... legal - nothing else */
269    if ((stp = rd_taske_or_proc_assign()) == NULL) return(NULL);
270    break;
271   default:
272    __pv_ferr(1062, "statement starting token expected - %s read",
273     __prt_vtok());
274    /* must advance one token here else end = uu; never advances */
275    __get_vtok();
276    __vskipto_any(SEMI);
277    return(NULL);
278  }
279  return(stp);
280 }
281 
282 /*
283  * read a sequential or fork/join block
284  * begin/fork read, reads end
285  * notice for unnamed begin-end block will return list of stmts
286  * with first have unb head turned on
287  */
rd_block(int32 btok,int32 endbtok)288 static struct st_t *rd_block(int32 btok, int32 endbtok)
289 {
290  int32 slcnt, sfnind;
291  struct st_t *stp, *hdstp;
292 
293  slcnt = __lin_cnt;
294  sfnind = __cur_fnam_ind;
295  __get_vtok();
296  if (__toktyp == COLON)
297   {
298    if (__iact_state)
299     {
300      /* cannot catch this later because no declarations in interactive */
301      __pv_err_cnt++;
302      __ia_err(1431, "named blocks illegal in interactive mode");
303      return(NULL);
304     }
305    /* task without params embedded in statement list */
306    __cur_declobj = TASK;
307    stp = rd_namblock(btok, endbtok, slcnt, sfnind);
308    __cur_declobj = MODULE;
309    return(stp);
310   }
311  /* first step is to read list of statements in block */
312  /* if all statements in error will look like empty statement */
313  if (!rd_lstofsts(endbtok, &hdstp, __lin_cnt, __cur_fnam_ind)) return(NULL);
314  if (btok == Begin)
315   {
316    if (hdstp != NULL)
317     {
318      hdstp->st_unbhead = TRUE;
319      /* correct to line of begin */
320      /* ---
321      hdstp->stfnam_ind = sfnind;
322      hdstp->stlin_cnt = slcnt;
323      -- */
324     }
325    return(hdstp);
326   }
327  /* this can never return nil */
328  stp = convert_to_fork(hdstp);
329  /* correct to line of fork */
330  /* SJM ??? UNDO FOR RELEASE ---
331  stp->stfnam_ind = sfnind;
332  stp->stlin_cnt = slcnt;
333  --- */
334  return(stp);
335 }
336 
337 /*
338  * convert a statement list to a fork-join statement
339  *
340  * at this point st nxt fields point to next in list
341  * converts to table where nexts all empty and nil at end of table
342  */
convert_to_fork(struct st_t * hdstp)343 static struct st_t *convert_to_fork(struct st_t *hdstp)
344 {
345  register int32 fji;
346  register struct st_t *stp;
347  int32 num_fjs;
348  struct st_t *stp2, *fjstp;
349 
350  /* first count how many */
351  for (num_fjs = 0, stp = hdstp; stp != NULL; stp = stp->stnxt)
352   {
353    /* SJM 09/24/01 - for assign followed by for pair count as one */
354    if (stp->stmttyp == S_FORASSGN) continue;
355    num_fjs++;
356   }
357 
358  /* know this is fork-join (never named) */
359  fjstp = __alloc_stmt(S_UNFJ);
360  /* one extra for nil fence at end */
361  fjstp->st.fj.fjstps = (struct st_t **)
362   __my_malloc((num_fjs + 1)*sizeof(struct st_t *));
363  fjstp->st.fj.fjlabs = (int32 *) __my_malloc((num_fjs + 1)*sizeof(int32));
364 
365  /* fill table of ptrs to stmts */
366  /* for now leaving begin-end as unnamed block - not making st. list */
367  /* even if empty (because of error) need body as NULL statement */
368  for (stp = hdstp, fji = 0; fji < num_fjs; fji++)
369   {
370    /* SJM 09/24/01 - for for need both S FOR ASSIGN and for as one "block" */
371    /* since unnamed begin end blocks are just lists, works */
372    /* notice other setup inserted not inserted by here so can ignore */
373    if (stp->stmttyp == S_FORASSGN)
374     {
375      stp2 = stp->stnxt->stnxt;
376      fjstp->st.fj.fjstps[fji] = stp;
377      fjstp->st.fj.fjlabs[fji] = -1;
378      stp->stnxt->stnxt = NULL;
379     }
380    else
381     {
382      stp2 = stp->stnxt;
383      fjstp->st.fj.fjstps[fji] = stp;
384      fjstp->st.fj.fjlabs[fji] = -1;
385      /* fork-join is exactly one statement - unnamed block if begin-end */
386      stp->stnxt = NULL;
387     }
388    stp = stp2;
389   }
390  /* set ending fence */
391  fjstp->st.fj.fjstps[num_fjs] = NULL;
392  fjstp->st.fj.fjlabs[num_fjs] = -1;
393  return(fjstp);
394 }
395 
396 /*
397  * read a statement list ending with block end token
398  * for contents of block, know block begin and optional label read
399  * reads block end token
400  * must use local variables since recursively nested blocks legal
401  */
rd_lstofsts(int32 endbtok,struct st_t ** stpp,int32 slcnt,int32 sfnind)402 static int32 rd_lstofsts(int32 endbtok, struct st_t **stpp, int32 slcnt,
403  int32 sfnind)
404 {
405  struct st_t *stp, *last_stp, *unbstp;
406 
407  /* block body statements may be missing i.e begin end ok */
408  last_stp = NULL;
409  if (__toktyp == endbtok)
410   {
411    stp = __alloc_stmt(S_STNONE);
412    stp->stfnam_ind = sfnind;
413    stp->stlin_cnt = slcnt;
414    *stpp = stp;
415    return(TRUE);
416   }
417  for (*stpp = NULL;;)
418   {
419    /* on error, this attempts to read to 1 before next statement token */
420    /* this expects 1st token of statement to have been read */
421    if ((stp = __rd_stmt()) == NULL)
422     {
423      if (__syncto_class == SYNC_STMT || __syncto_class == SYNC_TARG)
424       {
425        __get_vtok();
426        if (__toktyp == TEOF)
427         { __syncto_class = SYNC_FLEVEL; return(FALSE); }
428        continue;
429       }
430      /* know hit module or file level thing - think unresyncable */
431      return(FALSE);
432     }
433    /* if statement is unnamed block, change normal list to unnamed block */
434    /* need since in list next already used */
435    /* but need lists for blocks normally so can insert gotos, etc. */
436    if (stp->st_unbhead)
437     {
438      unbstp = __alloc_stmt(S_UNBLK);
439      unbstp->st.sbsts = stp;
440      unbstp->stfnam_ind = sfnind;
441      unbstp->stlin_cnt = slcnt;
442      stp = unbstp;
443     }
444    /* try to parse as much as possible even if errors */
445    if (last_stp == NULL) *stpp = stp; else last_stp->stnxt = stp;
446    /* for returns 2 statement list - since reading list just 1 longer */
447    if (stp->stmttyp == S_FORASSGN) last_stp = stp->stnxt;
448    else last_stp = stp;
449    __get_vtok();
450    if (__toktyp == endbtok) break;
451   }
452  return(TRUE);
453 }
454 
455 /*
456  * read a named block
457  * know : read and reads block end token
458  * notice named block linked on task list and from stmt
459  * also notice body is pointer to statement that may or may not be list
460  */
rd_namblock(int32 btok,int32 endbtok,int32 slcnt,int32 sfnind)461 static struct st_t *rd_namblock(int32 btok, int32 endbtok, int32 slcnt,
462  int32 sfnind)
463 {
464  struct task_t *sav_cur_tsk;
465  struct st_t *hdstp, *stp;
466 
467  __get_vtok();
468  if (__toktyp != ID)
469   {
470    __pv_ferr(1063, "block label expected - %s read - skipped",
471      __prt_kywrd_vtok());
472    /* here just assume left out */
473    strcpy(__token, "**filler**");
474    __toktyp = ID;
475    __unget_vtok();
476   }
477  /* save cur. task - since recursively called and on stack nesting, works */
478  sav_cur_tsk = __cur_tsk;
479 
480  /* this increments top sti and changes current task */
481  /* if error here, must give up - find like level end */
482  if (!__bld_tsk(__token, btok))
483   {
484    __find_matchendblk(btok, endbtok);
485    return(NULL);
486   }
487  /* illegal I/O decls here caught later */
488  __get_vtok();
489  /* allocate even though wasted if error since need line no. */
490  stp = __alloc_stmt(S_NAMBLK);
491  /* correct to line of begin */
492  stp->stlin_cnt = slcnt;
493  stp->stfnam_ind = sfnind;
494 
495  /* statement has a task body as it data */
496  stp->st.snbtsk = __cur_tsk;
497  /* also fill back ptr to the one location named block task in */
498  __cur_tsk->st_namblkin = stp;
499 
500  /* continues through all decls - even if error, if F then must give up */
501  /* T possible on error if hit statement */
502  if (!__rd_tfdecls("named block"))
503   {
504    __find_matchendblk(btok, endbtok);
505 bad_end:
506    __top_sti--;
507    __cur_tsk = sav_cur_tsk;
508    return(NULL);
509   }
510  /* according to grammar this must be a statement list */
511  /* format is begin/fork : [name] [decls?] [stmt list] end/join */
512  /* this will have sync to end of block - or mod/file level thing */
513  /* SJM 10/19/05 - line count and file arguments name were reversed */
514  if (!rd_lstofsts(endbtok, &hdstp, slcnt, sfnind)) goto bad_end;
515  __cur_tsk->tsk_last_lini = __lin_cnt;
516  __cur_tsk->tsk_last_ifi = __cur_fnam_ind;
517 
518  /* symbols no longer accessible */
519  __top_sti--;
520  if (btok == Begin) __cur_tsk->tskst = hdstp;
521  else __cur_tsk->tskst = convert_to_fork(hdstp);
522 
523  /* must link named block on task list */
524  if (__end_tbp == NULL) __inst_mod->mtasks = __cur_tsk;
525  else __end_tbp->tsknxt = __cur_tsk;
526  __end_tbp = __cur_tsk;
527 
528  __cur_tsk = sav_cur_tsk;
529  /* statement here is the pointer to the task */
530  return(stp);
531 }
532 
533 /*
534  * find a matching end block (end or join)
535  */
__find_matchendblk(int32 btok,int32 endbtok)536 extern void __find_matchendblk(int32 btok, int32 endbtok)
537 {
538  int32 blklev = 0;
539 
540  for (;;)
541   {
542    if (__syncto_class != SYNC_STMT) return;
543    if (__vskipto2_any(btok, endbtok))
544     {
545      if (__toktyp == endbtok) { if (blklev <= 0) return; blklev--; }
546      else blklev++;
547     }
548   }
549 }
550 
551 /*
552  * read if statement - if keyword read, reads statement end token
553  */
rd_if(void)554 static struct st_t *rd_if(void)
555 {
556  struct st_t *stp, *thenstp, *elsestp;
557  struct expr_t *ifxnd;
558  int32 slcnt, sfnind;
559 
560  slcnt = __lin_cnt;
561  sfnind = __cur_fnam_ind;
562  __get_vtok();
563  if (__toktyp != LPAR)
564   {
565    __pv_ferr(1064, "if not followed by required left parenthesis - %s read",
566     __prt_vtok());
567 sync_xpr:
568    __vskipto3_any(RPAR, ELSE, SEMI);
569    if (__syncto_class == SYNC_TARG)
570     {
571      __set_xtab_errval();
572      __bld_xtree(0);
573      ifxnd = __root_ndp;
574      if (__toktyp == RPAR) goto rd_then;
575      thenstp = __alloc_stmt(S_NULL);
576      if (__toktyp == ELSE) goto rd_else;
577      /* skipped to ; */
578      goto maybe_else;
579     }
580    if (__syncto_class == SYNC_STMT)
581     {
582      __set_xtab_errval();
583      __bld_xtree(0);
584      ifxnd = __root_ndp;
585      goto rd_then;
586     }
587    /* something completely out of place */
588    __get_vtok();
589    return(NULL);
590   }
591  __get_vtok();
592  /* collection routines that fail must emit error */
593  if (!__col_parenexpr(-1))
594   {
595    goto sync_xpr;
596   }
597  /* need to build and save expr */
598  __bld_xtree(0);
599  ifxnd = __root_ndp;
600 
601 rd_then:
602  __get_vtok();
603  if ((thenstp = __rd_stmt()) == NULL)
604   {
605    if (__syncto_class == SYNC_STMT || (__syncto_class == SYNC_TARG
606     && __toktyp == SEMI))
607     {
608      thenstp = __alloc_stmt(S_NULL);
609      goto maybe_else;
610     }
611    /* anything else - return and caller syncs */
612    return(NULL);
613   }
614 maybe_else:
615  __get_vtok();
616  if (__toktyp == ELSE)
617   {
618 rd_else:
619    __get_vtok();
620    if ((elsestp = __rd_stmt()) == NULL) return(NULL);
621   }
622  /* should try to get rid of this unget */
623  else
624   {
625    /* unget needed because routines expect to read 1st st. token */
626    if (__iact_state)
627     {
628      __pv_err_cnt++;
629      __ia_err(1432, "interactive if statement required else missing");
630      return(NULL);
631     }
632    __unget_vtok();
633    elsestp = NULL;
634   }
635  stp = __alloc_stmt(S_IF);
636  /* correct to line of if */
637  stp->stlin_cnt = slcnt;
638  stp->stfnam_ind = sfnind;
639 
640  stp->st.sif.condx = ifxnd;
641  stp->st.sif.thenst = thenstp;
642  stp->st.sif.elsest = elsestp;
643  return(stp);
644 }
645 
646 /*
647  * know case/casex,casez keyword read and reads endcase
648  */
rd_case(int32 casttyp)649 static struct st_t *rd_case(int32 casttyp)
650 {
651  struct st_t *casp, *dflsp, *stp;
652  struct csitem_t *cip, *last_cip, *csihdr, *dflt_csip;
653  struct expr_t *csndp;
654  struct exprlst_t *csixhdr, *xplp, *last_xplp;
655  int32 slcnt, sfnind;
656 
657  slcnt = __lin_cnt;
658  sfnind = __cur_fnam_ind;
659 
660  __get_vtok();
661  if (__toktyp != LPAR)
662   {
663    __pv_ferr(1065,
664     "case statement selection expression left parenthesis expected - %s read",
665     __prt_vtok());
666 bad_csx:
667    if (__vskipto2_any(RPAR, SEMI)) { __set_xtab_errval(); goto bld_csx; }
668    return(NULL);
669   }
670  __get_vtok();
671  if (!__col_parenexpr(-1)) goto bad_csx;
672 bld_csx:
673  __bld_xtree(0);
674  csndp = __root_ndp;
675  for (last_cip = NULL, csihdr = NULL, dflsp = NULL;;)
676   {
677    __get_vtok();
678    switch ((byte) __toktyp) {
679     case ENDCASE: goto bld_case;
680     case DEFAULT:
681 do_dflt:
682      __get_vtok();
683      if (__toktyp == COLON) __get_vtok();
684      if (dflsp != NULL)
685       __pv_ferr(1067, "more than one case default item not permitted");
686      if ((dflsp = __rd_stmt()) == NULL)
687       {
688        if (__vskipto_any(SEMI)) continue;
689        /* here must skip to endcase of right level and return */
690 give_up:
691        __find_matchendcase();
692        return(NULL);
693       }
694      continue;
695     default:
696      /* expr. collection will fail if not required one expr. */
697      for (last_xplp = NULL, csixhdr = NULL;;)
698       {
699 more_xprs:
700        if (!__col_caseexpr())
701         {
702          if (__vskipto3_any(COLON, SEMI, COMMA))
703           {
704            if (__toktyp == SEMI) goto nxt_case;
705            __set_xtab_errval();
706           }
707          else goto give_up;
708         }
709        __bld_xtree(0);
710        /* allocate and link in the expression list item */
711        xplp = __alloc_xprlst();
712        xplp->xp = __root_ndp;
713        if (last_xplp == NULL) csixhdr = xplp; else last_xplp->xpnxt = xplp;
714        last_xplp = xplp;
715 
716        if (__toktyp != COMMA) break;
717        __get_vtok();
718       }
719      if (__toktyp != COLON)
720       {
721        __pv_ferr(1068, "case item expression list colon expected - %s read",
722         __prt_vtok());
723        if (__vskipto3_any(COLON, SEMI, COMMA))
724         {
725          if (__toktyp == SEMI) continue;
726          if (__toktyp == COLON) goto do_cstmt;
727          goto more_xprs;
728         }
729        else goto give_up;
730       }
731 do_cstmt:
732      __get_vtok();
733      /* ; null statement ok here */
734      if ((casp = __rd_stmt()) == NULL)
735       {
736        if (__vskipto2_any(SEMI, DEFAULT))
737         {
738          if (__toktyp == DEFAULT) goto do_dflt;
739          continue;
740         }
741        else goto give_up;
742       }
743      /* allocate and link in the case item element */
744      cip = __alloc_csitem();
745      cip->csixlst = csixhdr;
746      cip->csist = casp;
747      if (last_cip == NULL) csihdr = cip; else last_cip->csinxt = cip;
748      last_cip = cip;
749    }
750 nxt_case:;
751   }
752 bld_case:
753  stp = __alloc_stmt(S_CASE);
754  /* correct to line of case */
755  stp->stlin_cnt = slcnt;
756  stp->stfnam_ind = sfnind;
757 
758  stp->st.scs.castyp = casttyp;
759  stp->st.scs.csx = csndp;
760 
761  /* SJM 08/27/99 - change so no default in case rec but first on item list */
762  dflt_csip = __alloc_csitem();
763  dflt_csip->csixlst = NULL;
764  /* no default: indicated by first nil */
765  if (dflsp != NULL) dflt_csip->csist = dflsp; else dflt_csip->csist = NULL;
766 
767  /* link onto front of list */
768  dflt_csip->csinxt = csihdr;
769  stp->st.scs.csitems = dflt_csip;
770  return(stp);
771 }
772 
773 /*
774  * find a matching endcase
775  */
__find_matchendcase(void)776 extern void __find_matchendcase(void)
777 {
778  int32 caselev = 0;
779  for (;;)
780   {
781    if (__syncto_class != SYNC_STMT) return;
782    if (__vskipto4_any(ENDCASE, CASE, CASEX, CASEZ))
783     {
784      if (__toktyp == ENDCASE) { if (caselev <= 0) return; caselev--; }
785      else caselev++;
786     }
787    else return;
788   }
789 }
790 
791 /*
792  * allocate an expression list element
793  */
__alloc_xprlst(void)794 extern struct exprlst_t *__alloc_xprlst(void)
795 {
796  struct exprlst_t *xplp;
797 
798  xplp = (struct exprlst_t *) __my_malloc(sizeof(struct exprlst_t));
799  xplp->xp = NULL;
800  xplp->xpnxt = NULL;
801  return(xplp);
802 }
803 
804 /*
805  * allocate a case item - case statement is list of case items
806  */
__alloc_csitem(void)807 extern struct csitem_t *__alloc_csitem(void)
808 {
809  struct csitem_t *cip;
810 
811  cip = (struct csitem_t *) __my_malloc(sizeof(struct csitem_t));
812  cip->csixlst = NULL;
813  cip->csist = NULL;
814  cip->csinxt = NULL;
815  return(cip);
816 }
817 
818 /*
819  * read a simple (non for) loop statement
820  */
rd_loop(int32 ttyp)821 static struct st_t *rd_loop(int32 ttyp)
822 {
823  struct st_t *stp, *repstp;
824  struct expr_t *loopx;
825  char s1[RECLEN];
826 
827  /* notice this is done at 1st statement so no line number fix up */
828  if (ttyp == REPEAT) stp = __alloc_stmt(S_REPEAT);
829  else if (ttyp == WAIT) stp = __alloc_stmt(S_WAIT);
830  else stp = __alloc_stmt(S_WHILE);
831  loopx = NULL;
832  repstp = NULL;
833 
834  switch ((byte) ttyp) {
835   case FOREVER:
836    /* first build proc assign */
837    stp->stmttyp = S_FOREVER;
838    loopx = NULL;
839    __get_vtok();
840    if ((repstp = __rd_stmt()) == NULL) return(NULL);
841    break;
842   case REPEAT:
843    stp->stmttyp = S_REPEAT;
844    goto get_expr;
845   case WHILE:
846    stp->stmttyp = S_WHILE;
847    goto get_expr;
848   case WAIT:
849    stp->stmttyp = S_WAIT;
850     /* here because wait expression globals need special xmrtype fields */
851 get_expr:
852    __get_vtok();
853    if (__toktyp != LPAR)
854     {
855      __pv_ferr(1070,
856       "%s loop statement conditional expression not preceded by left parenthesis - %s read",
857       __get_vkeynam(s1, ttyp), __prt_vtok());
858 sync_lpx:
859      if (__vskipto2_any(SEMI, RPAR))
860       {
861        if (__toktyp == RPAR) {  __set_xtab_errval(); goto bldx; }
862        __syncto_class = SYNC_STMT;
863       }
864      /* here have synced to beginning of next statement */
865      return(NULL);
866     }
867    __get_vtok();
868    if (!__col_parenexpr(-1)) goto sync_lpx;
869 bldx:
870    __bld_xtree(0);
871    loopx = __root_ndp;
872    __get_vtok();
873    if ((repstp = __rd_stmt()) == NULL) return(NULL);
874    break;
875    default: __case_terr(__FILE__, __LINE__);
876   }
877  /* repeat tmp per inst. storage filed not set till preparation phase */
878  if (stp->stmttyp == S_REPEAT)
879   { stp->st.srpt.repx = loopx; stp->st.srpt.repst = repstp; }
880  else if (stp->stmttyp == S_WAIT)
881   { stp->st.swait.lpx = loopx; stp->st.swait.lpst = repstp; }
882  else { stp->st.swh.lpx = loopx; stp->st.swh.lpst = repstp; }
883  return(stp);
884 }
885 
886 /*
887  * read a for statement
888  * know for token read and reads end of for body
889  * notice this returns 2 statement short list (since unnamed begin
890  * returns list - this always is ok)
891  */
rd_for(void)892 static struct st_t *rd_for(void)
893 {
894  struct for_t *frs;
895  struct st_t *stp, *inita, *inca, *forbd;
896  struct expr_t *lhsndp, *rhsndp, *stopndp;
897  int32 slcnt, sfnind;
898 
899  slcnt = __lin_cnt;
900  sfnind = __cur_fnam_ind;
901 
902  /* must read expressions separately for assigns */
903  /* first build initialization assign */
904  __get_vtok();
905  if (__toktyp != LPAR)
906   {
907    __pv_ferr(1071,
908     "for statement left parenthesis expected - %s read", __prt_vtok());
909 bad_for:
910    if (__vskipto2_any(RPAR, SEMI))
911     {
912      if (__toktyp == SEMI) { inita = __alloc_stmt(S_NULL); goto bldtrmx; }
913     }
914 rd_forst:
915    /* if module or file level item, just return caller will resync */
916    if (__syncto_class == SYNC_STMT || __syncto_class == SYNC_TARG)
917     {
918      __get_vtok();
919      __rd_stmt();
920     }
921    return(NULL);
922   }
923  __get_vtok();
924  /* collect lhs to = */
925  if (!__col_lval()) goto bad_for;
926  __bld_xtree(0);
927  lhsndp = __root_ndp;
928  __get_vtok();
929  if (!__col_comsemi(-1)) goto bad_for;
930  if (__toktyp != SEMI)
931   {
932    __pv_ferr(1076,
933     "for statement initial assignment ending semicolon expected - %s read",
934     __prt_vtok());
935    __vskipto_any(RPAR);
936    goto rd_forst;
937   }
938 
939  __bld_xtree(0);
940  rhsndp = __root_ndp;
941  /* build proc assign */
942  inita = __alloc_stmt(S_FORASSGN);
943  inita->st.spra.lhsx = lhsndp;
944  inita->st.spra.rhsx = rhsndp;
945 
946  /* build termination expression */
947 bldtrmx:
948  __get_vtok();
949  if (!__col_comsemi(-1))
950   {
951    if (__vskipto2_any(RPAR, SEMI))
952     {
953      if (__toktyp == SEMI) { __set_xtab_errval(); goto bldcondx; }
954     }
955    goto rd_forst;
956   }
957  if (__toktyp != SEMI)
958   {
959    __pv_ferr(1078,
960     "for statement termination expression ending semicolon expected - %s read",
961     __prt_vtok());
962    __vskipto_any(RPAR);
963    goto rd_forst;
964   }
965 
966 bldcondx:
967  __bld_xtree(0);
968  stopndp = __root_ndp;
969 
970  /* collect assignment ending in ) */
971  __get_vtok();
972  /* collect lhs to = - this can only end with = */
973  if (!__col_lval())
974   {
975 bad2_for:
976    if (__vskipto_any(RPAR)) { inca = __alloc_stmt(S_NULL); goto do_body; }
977    goto rd_forst;
978   }
979 
980  __bld_xtree(0);
981  lhsndp = __root_ndp;
982  __get_vtok();
983  if (!__col_parenexpr(-1)) goto bad2_for;
984  __bld_xtree(0);
985  rhsndp = __root_ndp;
986 
987  /* build proc assign */
988  inca = __alloc_stmt(S_PROCA);
989  inca->st.spra.lhsx = lhsndp;
990  inca->st.spra.rhsx = rhsndp;
991 
992 do_body:
993  __get_vtok();
994  if ((forbd = __rd_stmt()) == NULL) return(NULL);
995 
996  stp = __alloc_stmt(S_FOR);
997  /* correct to line of for */
998  stp->stlin_cnt = slcnt;
999  stp->stfnam_ind = sfnind;
1000 
1001  frs = stp->st.sfor;
1002  frs->forassgn = inita;
1003  frs->fortermx = stopndp;
1004  frs->forinc = inca;
1005  frs->forbody = forbd;
1006  /* notice for assign (initializer) inserted before for but for assgn */
1007  /* still points back to it */
1008  inita->stnxt = stp;
1009  return(inita);
1010 }
1011 
1012 /*
1013  * read a -> cause statement, know -> read and read ending ;
1014  */
rd_cause(void)1015 static struct st_t *rd_cause(void)
1016 {
1017  struct st_t *stp;
1018  struct sy_t *syp;
1019 
1020  __get_vtok();
1021  if (!__col_comsemi(-1))
1022   {
1023 skp_end:
1024    __vskipto_any(SEMI);
1025    return(NULL);
1026   }
1027  if (__toktyp != SEMI)
1028   {
1029    __pv_ferr(1072, "cause statement semicolon expected - %s read",
1030     __prt_vtok());
1031    goto skp_end;
1032   }
1033  __bld_xtree(0);
1034  /* this error does not effect synchronization */
1035  if (__root_ndp->optyp != ID && __root_ndp->optyp != GLBREF)
1036   __pv_ferr(1073, "cause statement event name expected");
1037  if (__toktyp == ID)
1038   {
1039    syp = __root_ndp->lu.sy;
1040    /* if net wire and not declared, convert to event wire */
1041    if (syp->sytyp == SYM_N && !syp->sydecl) syp->el.enp->ntyp = N_EVENT;
1042    /* declaration errors caught later */
1043   }
1044  stp = __alloc_stmt(S_CAUSE);
1045  stp->st.scausx = __root_ndp;
1046  return(stp);
1047 }
1048 
1049 /*
1050  * read a disable statement - must be check later
1051  * know disable read
1052  */
rd_disable(void)1053 static struct st_t *rd_disable(void)
1054 {
1055  struct st_t *stp;
1056  struct expr_t *dsxndp;
1057  struct expridtab_t *xidp;
1058 
1059  __get_vtok();
1060  if (!__col_comsemi(-1))
1061   {
1062    __vskipto_any(SEMI);
1063    return(NULL);
1064   }
1065  if (__toktyp != SEMI)
1066   {
1067    __pv_ferr(1129, "disable statement semicolon expected - %s read",
1068     __prt_vtok());
1069    return(NULL);
1070   }
1071  /* tricky code for simple local just ID task/named block disable */
1072  /* can not parse because will be found incorrectly as local wire */
1073  /* this is side effect of stupid xmr as expression new feature */
1074  /* ending fence undef not yet added because bld xtree not called */
1075  if (__last_xtk == 0 && __exprtab[0]->optyp == ID)
1076   {
1077    /* must allocate name of task or fixup if previously used */
1078    xidp = __expr_idtab[0];
1079    if ((dsxndp = find_bldxpr_tfsy(xidp->idnam, UNDEF)) == NULL) return(NULL);
1080 
1081    /* also can't disable funcs - because run in no time but caught later */
1082    stp = __alloc_stmt(S_DSABLE);
1083    stp->st.sdsable.dsablx = dsxndp;
1084    return(stp);
1085   }
1086  /* this must be xmr - because xmr now expressions must parse to construct */
1087  __bld_xtree(0);
1088  dsxndp = __root_ndp;
1089  if (dsxndp->optyp != GLBREF)
1090   {
1091    __pv_ferr(1074,
1092     "disable statement hierarchical named block or task name reference expected - %s read",
1093     __msgexpr_tostr(__xs, dsxndp));
1094    return(NULL);
1095   }
1096  stp = __alloc_stmt(S_DSABLE);
1097  stp->st.sdsable.dsablx = dsxndp;
1098  return(stp);
1099 }
1100 
1101 /*
1102  * find (and maybe add) task symbol - only called for enable/disable
1103  * know definition at top mod level and non gref
1104  * may get here on named block disable (tfsytyp UNDEF) or enable
1105  */
find_bldxpr_tfsy(char * nam,int32 tfsytyp)1106 static struct expr_t *find_bldxpr_tfsy(char *nam, int32 tfsytyp)
1107 {
1108  struct expr_t *enable_ndp;
1109  struct sy_t *syp;
1110 
1111  /* if id declared in currently accessible name evironment use it */
1112  if ((syp = __get_sym_env(nam)) != NULL)
1113   {
1114    /* if disable must check in disable statement fixup */
1115    if (tfsytyp != UNDEF)
1116     {
1117      /* error if declared or used as non task */
1118      /* illegal to enable or disable a function */
1119      switch ((byte) syp->sytyp) {
1120       case SYM_F: case SYM_I: case SYM_M: case SYM_PRIM: case SYM_UDP:
1121       case SYM_N: case SYM_DEF:
1122        {
1123 	char s1[RECLEN], s2[RECLEN];
1124 
1125         if (syp->sydecl) strcpy(s1, "declared"); else strcpy(s1, "used");
1126         __to_sytyp(s2, syp->sytyp);
1127         __pv_ferr(963, "task or named block %s previously %s as %s at %s",
1128 	 syp->synam, s1, s2, __bld_lineloc(__xs, syp->syfnam_ind,
1129          syp->sylin_cnt));
1130         return(NULL);
1131        }
1132      }
1133     }
1134    /* rest of fields gets filled later - notice no width not in expr */
1135    enable_ndp = __alloc_newxnd();
1136    enable_ndp->optyp = ID;
1137    enable_ndp->lu.sy = syp;
1138    return(enable_ndp);
1139   }
1140  /* error if not declared in interactive command input */
1141  if (__iact_state)
1142   {
1143    __pv_err_cnt++;
1144    __ia_err(1435, "task or named block %s undeclared", nam);
1145    return(NULL);
1146   }
1147 
1148  enable_ndp = __alloc_newxnd();
1149  enable_ndp->optyp = ID;
1150 
1151  /* here building the enable so just need to pass place holder - for fcall */
1152  /* need the parsed expr where its insides are changed to xmr */
1153  cnvt_forw_tfcall_1cmpglb(enable_ndp, nam, __cur_fnam_ind, __lin_cnt);
1154  return(enable_ndp);
1155 }
1156 
1157 /*
1158  * read proc. quasi-cont assign - normal wire assign but only enable when
1159  * time token moves here, force for wires and 2nd level of qc assign
1160  */
rd_wireassign(int32 qcattyp)1161 static struct st_t *rd_wireassign(int32 qcattyp)
1162 {
1163  struct st_t *stp;
1164  struct expr_t *lhsndp, *rhsndp;
1165 
1166  /* allocate at top (wastes storage on error) to get line no. right */
1167  stp = __alloc_stmt(S_QCONTA);
1168  /* collect lhs to = */
1169  __get_vtok();
1170  if (!__col_lval())
1171   {
1172 bad_qassgn:
1173    __vskipto_any(SEMI);
1174    return(NULL);
1175   }
1176  __bld_xtree(0);
1177  /* must check later to make sure lvalue */
1178  lhsndp = __root_ndp;
1179 
1180  __get_vtok();
1181  if (!__col_comsemi(-1)) goto bad_qassgn;
1182  if (__toktyp != SEMI)
1183   {
1184    char s1[RECLEN];
1185 
1186    if (qcattyp == FORCE) strcpy(s1, "force");
1187    else if (qcattyp == ASSIGN) strcpy(s1, "quasi-continuous assign");
1188    else __case_terr(__FILE__, __LINE__);
1189 
1190    __pv_ferr(1076, "%s statement ending semicolon expected - %s read", s1,
1191     __prt_vtok());
1192    goto bad_qassgn;
1193   }
1194  __bld_xtree(0);
1195  rhsndp = __root_ndp;
1196 
1197  /* build quasi cont. assign */
1198  stp->st.sqca->qcatyp = qcattyp;
1199  /* assume reg. form - requried for assign/deassign */
1200  stp->st.sqca->regform = TRUE;
1201  stp->st.sqca->qclhsx = lhsndp;
1202  stp->st.sqca->qcrhsx = rhsndp;
1203  stp->st.sqca->rhs_qcdlstlst = NULL;
1204  return(stp);
1205 }
1206 
1207 /*
1208  * read wire deassign/release (difference is force arg. can be wire)
1209  * form is deassign/release [lvalue];
1210  */
rd_wiredeassign(int32 qcdeattyp)1211 static struct st_t *rd_wiredeassign(int32 qcdeattyp)
1212 {
1213  struct st_t *stp;
1214 
1215  /* allocate at top (wastes storage on error) to get line no. right */
1216  stp = __alloc_stmt(S_QCONTDEA);
1217  /* collect lhs to = */
1218  __get_vtok();
1219  if (!__col_comsemi(-1))
1220   {
1221 skp_end:
1222    __vskipto_any(SEMI);
1223    return(NULL);
1224   }
1225  if (__toktyp == COMMA)
1226   {
1227    char s1[RECLEN];
1228 
1229    __pv_ferr(1077, "%s statement ending semicolon expected - %s read",
1230     __get_vkeynam(s1, qcdeattyp), __prt_vtok());
1231    goto skp_end;
1232   }
1233  __bld_xtree(0);
1234 
1235  /* build quasi cont. assign */
1236  stp->st.sqcdea.qcdatyp = qcdeattyp;
1237  /* assume reg. form */
1238  stp->st.sqcdea.regform = TRUE;
1239  stp->st.sqcdea.qcdalhs = __root_ndp;
1240  return(stp);
1241 }
1242 
1243 /*
1244  * read and build task enable or procedural assignment statement
1245  *
1246  * expects 1st lhs element (ID or '{')to have been read
1247  * reads stmt ending ;
1248  *
1249  * for assign builds blocking or non blocking rhs del ctrl assign
1250  * uses 1st token as location for both delay control and action stmt
1251  *
1252  * notice for assign not read here - lhs and rhs read separately
1253  * notice recovery here can just be skip to ; [if correct must appear]
1254  */
rd_taske_or_proc_assign(void)1255 static struct st_t *rd_taske_or_proc_assign(void)
1256 {
1257  int32 dtyp, is_nb, slcnt, sfnind, is_evctl_impl;
1258  struct st_t *stp, *dcstp;
1259  struct expr_t *lhsndp, *rhsndp, *delxndp, *repcntx;
1260  struct delctrl_t *dctp;
1261  struct paramlst_t *pmp;
1262  char s1[IDLEN];
1263 
1264  slcnt = __lin_cnt;
1265  sfnind = __cur_fnam_ind;
1266 
1267  /* collect lhs to '=' or '(' or ';' (for task enable) else fails */
1268  if (!col2_lval())
1269   {
1270 bad_assgn:
1271    __vskipto_any(SEMI);
1272    return(NULL);
1273   }
1274  /* case 1: ID task enable, not parsed need special task sy decl */
1275  if (__toktyp == LPAR || __toktyp == SEMI)
1276   {
1277    if (__last_xtk != 0 || __exprtab[0]->optyp != ID) goto try_parsing;
1278    /* on error returns nil and that is also returned from here */
1279    /* notice must copy expr idtab value because overwritten by parsing */
1280    strcpy(s1, __expr_idtab[0]->idnam);
1281    stp = __rd_tskenable(s1, NULL, FALSE);
1282    return(stp);
1283   }
1284 
1285 try_parsing:
1286  __bld_xtree(0);
1287  lhsndp = __root_ndp;
1288  /* case 1a: xmr task enable */
1289  if (__toktyp == LPAR || __toktyp == SEMI)
1290   {
1291    /* error if enable anything but xmr */
1292    if (lhsndp->optyp != GLBREF)
1293     {
1294      __pv_ferr(1086,
1295       "attempted task enable of %s - maybe assignment = missing",
1296       __msgexpr_tostr(__xs, lhsndp));
1297      goto bad_assgn;
1298     }
1299    stp = __rd_tskenable(NULL, lhsndp, TRUE);
1300    return(stp);
1301   }
1302 
1303  /* case 2: assign */
1304  /* for now block procedural assignment not supported */
1305  if (__toktyp == RELLE) is_nb = TRUE; else is_nb = FALSE;
1306  /* must check later to make sure lvalue */
1307 
1308  __get_vtok();
1309 
1310  /* handle optional rhs delay control */
1311  /* 10/27/00 SJM - add support for rhs repeat delay control forms */
1312  repcntx = NULL;
1313  if (__toktyp == REPEAT)
1314   {
1315    __get_vtok();
1316    /* surrounding parentheses required by syntax */
1317    if (__toktyp != LPAR)
1318     {
1319      __pv_ferr(3413,
1320       "repeat event control count expression beginning left parenthesis expected - %s read",
1321        __prt_vtok());
1322      goto bad_assgn;
1323     }
1324    __get_vtok();
1325    /* this read trailing left parenthsis - here syncing only to ; */
1326    if (!__col_parenexpr(-1)) goto bad_assgn;
1327 
1328    __bld_xtree(0);
1329    repcntx = __root_ndp;
1330    /* read the delay control so can sync to normal rhs event control case */
1331    __get_vtok();
1332    if (__toktyp != AT)
1333     {
1334      __pv_ferr(3414,
1335       "repeat event control count expression not followed by event control at sign - %s read",
1336       __prt_vtok());
1337      goto bad_assgn;
1338     }
1339    /* set flag and fall thru - now same as normal rhs event control */
1340   }
1341 
1342  dtyp = DC_NONE;
1343  if (__toktyp == SHARP || __toktyp == AT)
1344   {
1345    /* know this reads one past end of delay control */
1346    if ((delxndp = rd_delctrl(&dtyp, &is_evctl_impl)) == NULL)
1347     {
1348      if (dtyp == DC_EVENT && is_evctl_impl)
1349       {
1350        __pv_ferr(3427,
1351         "right hand side event control implicit form @(*) illegal");
1352       }
1353      goto bad_assgn;
1354     }
1355    if (dtyp == DC_EVENT) dtyp = DC_RHSEVENT;
1356    else if (dtyp == DC_DELAY) dtyp = DC_RHSDELAY;
1357   }
1358  else delxndp = NULL;
1359 
1360  /* this reads end ; */
1361  if (!__col_comsemi(-1)) goto bad_assgn;
1362  if (__toktyp != SEMI)
1363   {
1364    __pv_ferr(1078,
1365     "assignment statement ending semicolon expected - %s read", __prt_vtok());
1366    goto bad_assgn;
1367   }
1368 
1369  __bld_xtree(0);
1370  rhsndp = __root_ndp;
1371 
1372  /* first build proc assign */
1373  if (!is_nb)
1374   {
1375    if (dtyp == DC_RHSEVENT || dtyp == DC_RHSDELAY)
1376     stp = __alloc_stmt(S_RHSDEPROCA);
1377    else stp = __alloc_stmt(S_PROCA);
1378   }
1379  else stp = __alloc_stmt(S_NBPROCA);
1380  stp->st.spra.lhsx = lhsndp;
1381  stp->st.spra.rhsx = rhsndp;
1382  stp->stlin_cnt = slcnt;
1383  stp->stfnam_ind = sfnind;
1384 
1385  if (delxndp == NULL) return(stp);
1386 
1387  dcstp = __alloc_stmt(S_DELCTRL);
1388  dcstp->stlin_cnt = slcnt;
1389  dcstp->stfnam_ind = sfnind;
1390 
1391  dctp = dcstp->st.sdc;
1392  dctp->dctyp = dtyp;
1393  dctp->dc_delrep = DT_CMPLST;
1394  pmp = __alloc_pval();
1395  pmp->plxndp = delxndp;
1396  dctp->dc_du.pdels = pmp;
1397  /* 10/28/00 SJM - only indication of rep form is repeat cnt expr non nil */
1398  dctp->repcntx = repcntx;
1399  /* 06/11/02 SJM - need to indicate non blocking rhs ev ctrl in dc evnt */
1400  if (is_nb) dctp->dc_nblking = TRUE;
1401 
1402  dctp->dceschd_tevs = NULL;
1403 
1404  dctp->actionst = stp;
1405  return(dcstp);
1406 }
1407 
1408 /*
1409  * read a task enable (call) statement
1410  *
1411  *  '(' or ';' (if no args read and reads ending ;
1412  * need special parsing for system task since ,, form legal there
1413  */
__rd_tskenable(char * tknam,struct expr_t * glbndp,int32 is_glbenable)1414 extern struct st_t *__rd_tskenable(char *tknam, struct expr_t *glbndp,
1415  int32 is_glbenable)
1416 {
1417  register int32 i;
1418  int32 rd_semi, nd_glb_conv;
1419  struct sy_t *syp;
1420  struct st_t *stp;
1421  struct tskcall_t *tkcp;
1422  struct expr_t *last_fcomxp, *lop;
1423  struct expr_t *enable_ndp;
1424  struct systsk_t *stbp;
1425 
1426  rd_semi = FALSE;
1427  nd_glb_conv = FALSE;
1428  stbp = NULL;
1429  /*  case 1: parsed global ref enable */
1430  if (is_glbenable)
1431   {
1432    stp = __alloc_stmt(S_TSKCALL);
1433    tkcp = &(stp->st.stkc);
1434    /* notice there is no tkexp lu. sy here */
1435    tkcp->tsksyx = glbndp;
1436    tknam = glbndp->ru.grp->gnam;
1437    goto get_args;
1438   }
1439 
1440  /* DBG remove --- */
1441  if (tknam == NULL) __arg_terr(__FILE__, __LINE__);
1442  /* --- */
1443  /* case 2 simple ID enable - not parsed */
1444  if (*tknam == '$')
1445   {
1446    /* look up in special system func. and task symbol table */
1447    if ((syp = __get_sym(tknam, __syssyms)) == NULL)
1448     {
1449      /* this is completely unknown case */
1450      __pv_ferr(1083,
1451       "task enable of unknown system task or undefined PLI task \"%s\"",
1452       tknam);
1453      goto err_end;
1454     }
1455    stbp = syp->el.esytbp;
1456    if (syp->sytyp != SYM_STSK)
1457     {
1458      __pv_ferr(1080, "task enable of system function \"%s\" illegal",
1459       syp->synam);
1460      goto err_end;
1461     }
1462    /* systam task table inconsistent - value is 0 */
1463    if (stbp->stsknum == 0) __misc_fterr(__FILE__, __LINE__);
1464 
1465    /* need location for xmr type setting */
1466    switch (stbp->stsknum) {
1467     case STN_MONITOR: case STN_MONITORB: case STN_MONITORH: case STN_MONITORO:
1468      if (__iact_state && __optimized_sim)
1469       {
1470 opt_dbg_illegal:
1471        /* SJM 01/02/03 - can't call $dumpvars system task from iact */
1472        /* from interactive debugger if -O on */
1473        __pv_ferr(2901,
1474         "system task %s can't be called from debugger when optimizer on - run without -O",
1475         syp->synam);
1476        goto err_end;
1477       }
1478      break;
1479     /* these can have module/inst. ending xmrs */
1480     case STN_DUMPVARS:
1481      if (__iact_state && __optimized_sim) goto opt_dbg_illegal;
1482      nd_glb_conv = TRUE;
1483      break;
1484     case STN_SDF_ANNOTATE:
1485     case STN_PRINTTIMESCALE: case STN_SCOPE: case STN_LIST:
1486      nd_glb_conv = TRUE;
1487      break;
1488     default:
1489      /* PLI system tasks/functions always allow XMR's */
1490      if (stbp->stsknum >= BASE_VERIUSERTFS
1491       && (int32) stbp->stsknum <= __last_systf) nd_glb_conv = TRUE;
1492      break;
1493    }
1494    enable_ndp = __alloc_newxnd();
1495    enable_ndp->optyp = ID;
1496    enable_ndp->lu.sy = syp;
1497   }
1498  else
1499   {
1500    /* if user task not declared must add to symbol table */
1501    /* return of NULL to here on error - message already written */
1502    if ((enable_ndp = find_bldxpr_tfsy(tknam, SYM_TSK)) == NULL)
1503     {
1504 err_end:
1505      __vskipto_any(SEMI);
1506      return(NULL);
1507     }
1508   }
1509  /* build the task enable statement */
1510  stp = __alloc_stmt(S_TSKCALL);
1511  tkcp = &(stp->st.stkc);
1512  tkcp->tsksyx = enable_ndp;
1513 
1514 get_args:
1515  tkcp->targs = NULL;
1516  /* no arguments */
1517  if (__toktyp == SEMI) goto done;
1518 
1519  /* build argument expressions in a list */
1520  __get_vtok();
1521  /* at this point ,, form ok (legal for system tasks? */
1522  for (last_fcomxp = NULL, i = 0;; i++)
1523   {
1524    /* ,, or ,) need to be check/fixed later */
1525    /* for display and other system task legal, but for user task error */
1526    if (__toktyp == COMMA || __toktyp == RPAR)
1527     {
1528      /* for xmr task enable, point to gnam - need for sys task testing */
1529      /* error messages */
1530      if (*tknam != '$')
1531       {
1532        __pv_ferr(1081,
1533         "user task %s enable empty '()' or ',,' argument form illegal (pos. %d)",
1534         tknam, i + 1);
1535        /* if error build rhs x, cannot be op empty for non system task */
1536        __set_xtab_errval();
1537       }
1538      else { __last_xtk = 0; __set_opempty(0); }
1539      goto do_parse;
1540     }
1541    /* by case code to allow special forms, made globals here */
1542    if (nd_glb_conv)
1543     {
1544      switch (stbp->stsknum) {
1545       /* for dumpvars all but 1st argument can be special form */
1546       case STN_DUMPVARS:
1547        if (i != 0) __allow_scope_var = TRUE;
1548        break;
1549       case STN_SDF_ANNOTATE:
1550        if (i == 1) __allow_scope_var = TRUE;
1551        break;
1552       /* case where all inst. forms */
1553       case STN_SCOPE: case STN_LIST: case STN_PRINTTIMESCALE:
1554        __allow_scope_var = TRUE;
1555        break;
1556       default:
1557        /* any argument to PLI system task can be xmr */
1558        if (stbp->stsknum >= BASE_VERIUSERTFS
1559         && (int32) stbp->stsknum <= __last_systf)
1560         {
1561          __allow_scope_var = TRUE;
1562         }
1563        else __case_terr(__FILE__, __LINE__);
1564      }
1565     }
1566    /* either path here turns off allowing scope var */
1567    if (!__col_connexpr(-1))
1568     {
1569      __allow_scope_var = FALSE;
1570      if (__vskipto3_any(COMMA, RPAR, SEMI))
1571       { if (__toktyp == SEMI) rd_semi = TRUE; }
1572      else goto err_end;
1573      /* if error build rhs x, then parse */
1574      __set_xtab_errval();
1575     }
1576 
1577 do_parse:
1578    __bld_xtree(0);
1579    /* parsing in bld xtree used this flag to allow inst. ending global */
1580    /* so now must turn off in case turned on */
1581    __allow_scope_var = FALSE;
1582 
1583    /* first arg. done for dumpvars - rest special inst xmr or wire form */
1584    lop = __alloc_newxnd();
1585    lop->optyp = FCCOM;
1586    lop->ru.x = NULL;
1587    lop->lu.x = __root_ndp;
1588 
1589    if (last_fcomxp == NULL) tkcp->targs = lop; else last_fcomxp->ru.x = lop;
1590    last_fcomxp = lop;
1591    /* some kind of error, seen ;, all done - probably more errors */
1592    if (__toktyp == rd_semi) goto done;
1593    if (__toktyp == RPAR) break;
1594    __get_vtok();
1595   }
1596  /* assume just left out */
1597  __get_vtok();
1598  if (__toktyp != SEMI)
1599   {
1600    __pv_ferr(1084,
1601     "task enable statement semicolon expected - %s read", __prt_vtok());
1602   }
1603 done:
1604  return(stp);
1605 }
1606 
1607 /*
1608  * read a delay/event control statement (non rhs)
1609  */
rd_dctrl_st(void)1610 static struct st_t *rd_dctrl_st(void)
1611 {
1612  int32 dtyp, slcnt, sfnind, is_evctl_impl;
1613  struct st_t *dcstp, *stp;
1614  struct expr_t *delxndp;
1615  struct delctrl_t *dctp;
1616  struct paramlst_t *pmp;
1617 
1618  slcnt = __lin_cnt;
1619  sfnind = __cur_fnam_ind;
1620  is_evctl_impl = FALSE;
1621  /* this reads one past one control or one past ending ) */
1622  /* only NULL error if cannot sync to following stmt */
1623  if ((delxndp = rd_delctrl(&dtyp, &is_evctl_impl)) == NULL)
1624   {
1625    /* SJM 06/01/04 - @(*) or @* forms - have nil delxndp but still bld */
1626    if (!is_evctl_impl) return(NULL);
1627   }
1628  dcstp = __alloc_stmt(S_DELCTRL);
1629  /* fix up so statement location starts with delay control not action stmt */
1630  dcstp->stlin_cnt = slcnt;
1631  dcstp->stfnam_ind = sfnind;
1632 
1633  dctp = dcstp->st.sdc;
1634  dctp->dctyp = dtyp;
1635  dctp->dc_delrep = DT_CMPLST;
1636  pmp = __alloc_pval();
1637  pmp->plxndp = delxndp;
1638  dctp->dc_du.pdels = pmp;
1639  dctp->dceschd_tevs = NULL;
1640  /* SJM 06/01/04 - in this case del xndp nil - build ev list during fixup */
1641  dctp->implicit_evxlst = is_evctl_impl;
1642 
1643  /* if begin-end block will return statement list */
1644  if ((stp = __rd_stmt()) == NULL) return(NULL);
1645  /* need some statement here even if it is only NULL statement */
1646  /* delay control on block turned into delay control on st. list */
1647  dctp->actionst = stp;
1648  return(dcstp);
1649 }
1650 
1651 /*
1652  * read a delay control @ or # read - builds expression and type
1653  * know first token read and reads one past ending token
1654  *
1655  * this must have skipped past delay control to stmt if possible
1656  */
rd_delctrl(int32 * dtyp,int32 * ev_impl)1657 static struct expr_t *rd_delctrl(int32 *dtyp, int32 *ev_impl)
1658 {
1659  struct expr_t *ndp;
1660 
1661  *ev_impl = FALSE;
1662  /* read one after except for non parenthesized ID because there need to */
1663  /* read one ahead to see if xmr */
1664  if (__toktyp == SHARP) *dtyp = DC_DELAY;
1665  else
1666   {
1667    *dtyp = DC_EVENT;
1668    __canbe_impl_evctrl = TRUE;
1669   }
1670  __get_vtok();
1671 
1672  if (__toktyp == LPAR)
1673   {
1674    /* if @(* that looks like attribute to scanner - glb canbe impl evctrl */
1675    /* on will prevent seeing as atrribute since attrs illegal here */
1676    __get_vtok();
1677    __canbe_impl_evctrl = FALSE;
1678 
1679    if (*dtyp == DC_DELAY)
1680     {
1681      /* undeclared names treated as wires - maybe changed to event later */
1682      /* need to surround with () in expr. so m:t:m parses ok */
1683      /* but need to use actual surrounding for parse indicators */
1684      __last_xtk = -1;
1685      ndp = __alloc_exprnd();
1686      ndp->optyp = LPAR;
1687      /* if no error, surround with parentheseses and parse as normal */
1688      if (!__col_parenexpr(0))
1689       {
1690        __pv_ferr(1278, "delay control expression error");
1691 
1692        __vskipto_any(RPAR);
1693        if (__syncto_class == SYNC_TARG || __syncto_class == SYNC_STMT)
1694         {
1695 bad_dctrl:
1696          /* this is 1 bit x - cannot be op empty */
1697          __set_xtab_errval();
1698          __get_vtok();
1699          goto bld_evx;
1700         }
1701        __get_vtok();
1702        return(NULL);
1703       }
1704      ndp = __alloc_exprnd();
1705      ndp->optyp = RPAR;
1706     }
1707    else
1708     {
1709      if (__toktyp == TIMES)
1710       {
1711        __get_vtok();
1712        if (__toktyp != RPAR)
1713         {
1714          __pv_ferr(3428, "implicit @(*) event control form illegal - %s read",
1715           __prt_vtok());
1716          __vskipto_any(RPAR);
1717          if (__syncto_class == SYNC_TARG || __syncto_class == SYNC_STMT)
1718           return(NULL);
1719          else { __get_vtok(); return(NULL); }
1720         }
1721        *ev_impl = TRUE;
1722        __get_vtok();
1723        return(NULL);
1724       }
1725 
1726      /* event control cannot have added surrounding () because of evor */
1727      if (!col_evctrlexpr())
1728       {
1729        __pv_ferr(1087, "event control expression error");
1730        /* if possible, now ready to read statement */
1731        __vskipto_any(RPAR);
1732        if (__syncto_class == SYNC_TARG || __syncto_class == SYNC_STMT)
1733         goto bad_dctrl;
1734        __get_vtok();
1735        return(NULL);
1736       }
1737     }
1738    /* on any non error surrounding () case, read one after end ) */
1739    __get_vtok();
1740   }
1741  else
1742   {
1743    /* turn off glb to prevent seeing @(* as scanner attribute */
1744    __canbe_impl_evctrl = FALSE;
1745 
1746    /* simple case can be one name form */
1747    /* should really check to see if next token can start stmt */
1748    __last_xtk = -1;
1749    /* this declares ID as wire - maybe later declared to be event */
1750    /* LOOKATME - could collect xmr without surrounding () by */
1751    /* looking for each .ID(optional [...]) after first */
1752    switch ((byte) __toktyp) {
1753     case NUMBER: case REALNUM: case ID: break;
1754     /* only create IS number at param assign */
1755     case TIMES:
1756      /* AIV 07/21/04 - handle @* without () */
1757      *ev_impl = TRUE;
1758       __get_vtok();
1759      return(NULL);
1760     case ISNUMBER: case ISREALNUM:
1761     /* here on error, assume right structure but 1 thing wrong */
1762      __arg_terr(__FILE__, __LINE__);
1763      break;
1764     default:
1765      /* one token after delay/event control case - no sync possible */
1766      __pv_ferr(1088,
1767      "non parenthesized delay/event control not identifier or number - %s read",
1768       __prt_vtok());
1769      goto bad_dctrl;
1770     }
1771    if (__toktyp == ID)
1772     {
1773      /* even if simple ID (i.e. always) this reads one past end */
1774      if (!col_dctrl_xmr()) goto bad_dctrl;
1775     }
1776    else
1777     {
1778      if (!__bld_expnode()) goto bad_dctrl;
1779      __get_vtok();
1780     }
1781   }
1782 bld_evx:
1783  if (*dtyp == DC_EVENT) __bld_evxtree(); else __bld_xtree(0);
1784  return(__root_ndp);
1785 }
1786 
1787 /*
1788  * collect a delay or event control variable
1789  *
1790  * know @ or # and following ID read - done unless part of XMR
1791  * after ID can have optional select [..] then if not dot done else read
1792  * next component - collected XMR later parsed into glbref
1793  *
1794  * know ID read and reads one past end of XMR (if not simple ID)
1795  * also emits error on non ID or GLBREF - select at end illegal - need ()
1796  */
col_dctrl_xmr(void)1797 static int32 col_dctrl_xmr(void)
1798 {
1799  int32 sblevel;
1800 
1801  __last_xtk = -1;
1802  if (!__bld_expnode()) goto bad_end;
1803  for (;;)
1804   {
1805    /* each time hear know ID read and added to exprtab */
1806    __get_vtok();
1807    if (__toktyp == LSB)
1808     {
1809      if (!__bld_expnode()) goto bad_end;
1810      for (sblevel = 0;;)
1811       {
1812        __get_vtok();
1813        if (__toktyp == TEOF || __toktyp == SEMI)
1814         {
1815          __pv_ferr(1082,
1816           "illegal token %s in delay or event control global variable",
1817           __prt_vtok());
1818          goto bad_end;
1819         }
1820        if (__toktyp == LSB) sblevel++;
1821        else if (__toktyp == RSB)
1822         {
1823          if (sblevel <= 0) break;
1824          sblevel--;
1825         }
1826        if (!__bld_expnode()) goto bad_end;
1827       }
1828      if (!__bld_expnode()) goto bad_end;
1829      __get_vtok();
1830      if (__toktyp != DOT)
1831       {
1832        __pv_ferr(1075,
1833         "delay or event control global variable contains select - must surround with parentheses");
1834        goto bad_end;
1835       }
1836     }
1837    /* anything after component but dot ends and not collected */
1838    /* works because this reads one past end */
1839    if (__toktyp != DOT) return(TRUE);
1840    if (!__bld_expnode()) goto bad_end;
1841    /* read required ID after DOT */
1842    __get_vtok();
1843    if (__toktyp != ID)
1844     {
1845      __pv_ferr(1058,
1846       "delay/event control hierarchical reference identifier must follow dot - %s read",
1847       __prt_kywrd_vtok());
1848     }
1849    if (!__bld_expnode()) goto bad_end;
1850   }
1851 
1852 bad_end:
1853  __set_xtab_errval();
1854  return(FALSE);
1855 }
1856 
1857 /*
1858  * EXPRESSION COLLECTION ROUTINES
1859  * these return FALSE and 1'bx on error - caller must emit err
1860  */
1861 
1862 /*
1863  * collect delay expr. make 0 if error - will never make it to fixup so ok
1864  * this collects and adds surrounding parenthesis - need for possible
1865  * min:typ:max with surrounding ()
1866  * but otherwise is identical to collect connecting expr.
1867  * expects 1st token to have been read
1868  */
__col_delexpr(void)1869 extern int32 __col_delexpr(void)
1870 {
1871  struct expr_t *ndp;
1872 
1873  __last_xtk = -1;
1874  ndp = __alloc_exprnd();
1875  ndp->optyp = LPAR;
1876  /* if no error, surround with parentheseses and parse as normal */
1877  if (!__col_connexpr(0))
1878   {
1879 bad_del:
1880    __set_xtab_errval();
1881    /* need constant 32 bit 0 here */
1882    __exprtab[0]->szu.xclen = WBITS;
1883    __exprtab[0]->ru.xvi = __alloc_shareable_cval(0, 0, WBITS);
1884    return(FALSE);
1885   }
1886  /* if col conn T, then know at least 1 token */
1887  if (__last_xtk == 1 && __exprtab[1]->optyp == OPEMPTY)
1888   {
1889    __pv_ferr(1095, "empty delay expression illegal");
1890    goto bad_del;
1891   }
1892  ndp = __alloc_exprnd();
1893  ndp->optyp = RPAR;
1894  return(TRUE);
1895 }
1896 
1897 
1898 /*
1899  * collect parm or specparam rhs parameter value
1900  * this collects and adds surrounding parenthesis
1901  * needed for possible min:typ:max with surrounding ()
1902  * but otherwise is identical to collect comsemi
1903  * expects 1st token to have been read
1904  *
1905  * on error sets value to 0 not x - is this right?
1906  * if this is used where only ; can end, caller must check for and emit err
1907  */
__col_paramrhsexpr(void)1908 extern int32 __col_paramrhsexpr(void)
1909 {
1910  struct expr_t *ndp;
1911 
1912  __last_xtk = -1;
1913  ndp = __alloc_exprnd();
1914  ndp->optyp = LPAR;
1915  /* if no error, surround with parentheseses and parse as normal */
1916  if (!__col_comsemi(0))
1917   {
1918    __set_xtab_errval();
1919    /* need constant 32 bit 0 here */
1920    __exprtab[0]->szu.xclen = WBITS;
1921    __exprtab[0]->ru.xvi = __alloc_shareable_cval(0, 0, WBITS);
1922    return(FALSE);
1923   }
1924  ndp = __alloc_exprnd();
1925  ndp->optyp = RPAR;
1926  return(TRUE);
1927 }
1928 
1929 /*
1930  * collect paren surround expression and leave tree in __exprtab[0]
1931  * expects 1st expr. token to have been read (after '(') reads end token
1932  * need to reuse or move nodes here to tree
1933  * surrounding parentheses not included
1934  */
__col_parenexpr(int32 start_xtk)1935 extern int32 __col_parenexpr(int32 start_xtk)
1936 {
1937  int32 parlevel;
1938 
1939  /* this is illegal () case */
1940  if (__toktyp == RPAR)
1941   {
1942    __pv_ferr(1089, "empty parentheses ending expression illegal");
1943 bad_end:
1944    /* notice cannot free here since in __exprtab (links just overwritten) */
1945    /* also make look like empty expr. */
1946    __set_xtab_errval();
1947    return(FALSE);
1948   }
1949  parlevel = 0;
1950  if (__toktyp == LPAR) parlevel++;
1951 
1952  for (__last_xtk = start_xtk;;)
1953   {
1954    if (!__bld_expnode()) goto bad_end;
1955    __get_vtok();
1956    if (__toktyp == LPAR) parlevel++;
1957    else if (__toktyp == RPAR)
1958     {
1959      if (parlevel > 0) parlevel--; else break;
1960     }
1961    else if (__toktyp == TEOF || __toktyp == SEMI)
1962     {
1963      if (__pv_err_cnt <= __saverr_cnt)
1964       __pv_ferr(1090, "illegal token %s in parenthesis ending expression",
1965        __prt_vtok());
1966      goto bad_end;
1967     }
1968   }
1969  return(TRUE);
1970 }
1971 
1972 /*
1973  * collect event expr - for new VER 2001 , as alternative to evor legal
1974  * same as collect paren expr except commas allowed and special
1975  * ev or comma token substituted
1976  *
1977  * expects 1st expr. token to have been read (after '(') reads end token
1978  *
1979  * know implicit @* and @(*) never seen here
1980  * need to reuse or move nodes here to tree
1981  */
col_evctrlexpr(void)1982 static int32 col_evctrlexpr(void)
1983 {
1984  int32 parlevel, catlevel;
1985 
1986  __last_xtk = -1;
1987  /* this is illegal () case */
1988  if (__toktyp == RPAR)
1989   {
1990    __pv_ferr(1089, "empty parentheses ending expression illegal");
1991 bad_end:
1992    /* notice cannot free here since in __exprtab (links just overwritten) */
1993    /* also make look like empty expr. */
1994    __set_xtab_errval();
1995    return(FALSE);
1996   }
1997  parlevel = catlevel = 0;
1998  if (__toktyp == LPAR) parlevel++;
1999  /* AIV 09/27/06 - catlevel was off for first case LCB */
2000  /* was incorrectly handling @({a, b}) */
2001  if (__toktyp == LCB) catlevel++;
2002 
2003  for (;;)
2004   {
2005    /* SJM 06/01/04 - this is unusual ',' just like event "or" but different */
2006    /* expr node op typ */
2007    /* bld expnode can't see comma because mashes error recovery */
2008    if (__toktyp == COMMA && catlevel == 0) __toktyp = OPEVCOMMAOR;
2009    if (!__bld_expnode()) goto bad_end;
2010 
2011    __get_vtok();
2012    switch ((byte) __toktyp) {
2013     case LCB: catlevel++; break;
2014     case RCB: catlevel--; break;
2015     case LPAR: parlevel++; break;
2016     case RPAR:
2017      /* only non nested rpar can cause correct exit */
2018      if (parlevel > 0) { parlevel--; break; }
2019      goto done;
2020     default:
2021      if (__toktyp == TEOF || __toktyp == SEMI)
2022       {
2023        if (__pv_err_cnt <= __saverr_cnt)
2024         {
2025          __pv_ferr(1090, "illegal token %s in parenthesis ending expression",
2026           __prt_vtok());
2027         }
2028        goto bad_end;
2029       }
2030     }
2031   }
2032 done:
2033  return(TRUE);
2034 }
2035 
2036 /*
2037  * collect a range expression
2038  * expects first token ([) to have been read and reads ending ] token
2039  * includes ] in expression
2040  */
__col_rangeexpr(void)2041 extern int32 __col_rangeexpr(void)
2042 {
2043  int32 brklevel;
2044  struct expr_t *ndp;
2045 
2046  /* must add dummy symbol so range parses as x[cexpr:cexpr] */
2047  __last_xtk = -1;
2048  ndp = __alloc_exprnd();
2049  ndp->optyp = ID;
2050  /* need dummy to fill id table - not used and overwritten each time */
2051  /* this checked for during term parsing and not decled */
2052  __alloc_expridnd("[]");
2053  /* node for already read [ */
2054  if (!__bld_expnode()) goto bad_end;
2055 
2056  for (brklevel = 0;;)
2057   {
2058    __get_vtok();
2059    if (__toktyp == LSB) brklevel++;
2060    else if (__toktyp == RSB)
2061     {
2062      if (brklevel <= 0)
2063       {
2064        if (__last_xtk == 1)
2065         {
2066          __pv_ferr(1097, "select range empty form ([]) illegal");
2067          goto bad_end;
2068         }
2069        /* ending ] must be part of expression */
2070        if (!__bld_expnode()) goto bad_end;
2071        break;
2072       }
2073      else brklevel--;
2074     }
2075    else if (__toktyp == TEOF || __toktyp == SEMI)
2076     {
2077      if (__pv_err_cnt <= __saverr_cnt)
2078       __pv_ferr(1091, "illegal token %s in select range expression",
2079        __prt_vtok());
2080 
2081 bad_end:
2082      /* must be 1 bit x not unc. */
2083      __set_xtab_errval();
2084      __last_xtk = 0;
2085      return(FALSE);
2086     }
2087    if (!__bld_expnode()) goto bad_end;
2088   }
2089  return(TRUE);
2090 }
2091 
2092 /*
2093  * collect an inst., port header, function call, delay, cat expr. or
2094  * instance pound parameter list
2095  *
2096  * expects 1st token to be read and read ending token
2097  * ends with ) or ,
2098  * allows full expressions but also used for param subset exprs.
2099  * need start_xtk for delay params where min:typ:max does not need (),
2100  * scheme adds surrounding () and then calls normal bld_xtree
2101  * for each comma sep.  * piece
2102  * normal start of expr. is -1
2103  */
__col_connexpr(int32 start_xtk)2104 extern int32 __col_connexpr(int32 start_xtk)
2105 {
2106  int32 parlevel, catlevel;
2107 
2108  /* ,, or ,) form ok here - if not caller will check */
2109  if (__toktyp == COMMA || __toktyp == RPAR)
2110   { __last_xtk = start_xtk + 1; __set_opempty(__last_xtk); return(TRUE); }
2111 
2112  for (__last_xtk = start_xtk, parlevel = 0, catlevel = 0;;)
2113   {
2114    switch ((byte) __toktyp) {
2115     case LPAR: parlevel++; break;
2116     case LCB: catlevel++; break;
2117     case RPAR:
2118      if (parlevel <= 0 && catlevel <= 0) return(TRUE); else parlevel--;
2119      break;
2120    case RCB:
2121     catlevel--;
2122     break;
2123    case COMMA:
2124     if (parlevel <= 0 && catlevel <= 0) return(TRUE);
2125     break;
2126    case TEOF:
2127    case SEMI:
2128     if (__pv_err_cnt <= __saverr_cnt)
2129      __pv_ferr(1092, "illegal token %s in expression list", __prt_vtok());
2130     goto bad_end;
2131    }
2132    if (!__bld_expnode()) goto bad_end;
2133    __get_vtok();
2134   }
2135 
2136 bad_end:
2137  __set_xtab_errval();
2138  return(FALSE);
2139 }
2140 
2141 /*
2142  * collect something from an assignment list rhs
2143  * expects 1st token of assignment rhs expr to have been read
2144  * rhs expr. can have (..) function calls and concatenates
2145  * also (..) delay triples
2146  *
2147  * reads trailing , or ;
2148  * empty here will not collect - error
2149  */
__col_comsemi(int32 last_xti)2150 extern int32 __col_comsemi(int32 last_xti)
2151 {
2152  int32 parlevel, catlevel;
2153 
2154  __last_xtk = last_xti;
2155  for (parlevel = 0, catlevel = 0;;)
2156   {
2157    switch ((byte) __toktyp) {
2158     case LPAR: parlevel++; break;
2159     case RPAR: parlevel--; break;
2160     case LCB: catlevel++; break;
2161     case RCB: catlevel--; break;
2162     case SEMI:
2163 chk_empty:
2164      /* empty = ; form illegal */
2165      if (__last_xtk == last_xti)
2166       {
2167        __pv_ferr(1106, "right hand side expression missing");
2168        goto bad_end;
2169       }
2170      return(TRUE);
2171     case COMMA:
2172      if (parlevel <= 0 && catlevel <= 0) goto chk_empty;
2173      break;
2174     case TEOF:
2175      if (__pv_err_cnt <= __saverr_cnt)
2176       __pv_ferr(1093, "illegal token %s in right hand side expression",
2177        __prt_vtok());
2178      goto bad_end;
2179    }
2180    if (!__bld_expnode()) goto bad_end;
2181    __get_vtok();
2182   }
2183 
2184 bad_end:
2185  /* replace entire expression with 1 bit x - not op empty */
2186  __set_xtab_errval();
2187  return(FALSE);
2188 }
2189 
2190 /*
2191  * new parameter format collect param (not specify) rhs expr
2192  *
2193  * expects 1st token of assignment rhs expr to have been read
2194  * and reads one past end , or ;
2195  *
2196  * for mismatched nesting parse will catch error
2197  */
__col_newparamrhsexpr(void)2198 extern int32 __col_newparamrhsexpr(void)
2199 {
2200  int32 parlevel, catlevel;
2201  struct expr_t *ndp;
2202 
2203  __last_xtk = -1;
2204  ndp = __alloc_exprnd();
2205  ndp->optyp = LPAR;
2206  for (parlevel = 0, catlevel = 0;;)
2207   {
2208    switch ((byte) __toktyp) {
2209     case LPAR: parlevel++; break;
2210     case RPAR: parlevel--; break;
2211     case LCB: catlevel++; break;
2212     case RCB: catlevel--; break;
2213     case SEMI:
2214 chk_empty:
2215      /* empty = ; form illegal */
2216      if (__last_xtk == -1)
2217       {
2218        __pv_ferr(1106, "right hand side expression missing");
2219        goto bad_end;
2220       }
2221      ndp = __alloc_exprnd();
2222      ndp->optyp = RPAR;
2223      return(TRUE);
2224     case COMMA:
2225      if (parlevel <= 0 && catlevel <= 0) goto chk_empty;
2226      break;
2227     case TEOF:
2228      if (__pv_err_cnt <= __saverr_cnt)
2229       __pv_ferr(1093,
2230        "illegal token %s in parameter right hand side expression",
2231        __prt_vtok());
2232      goto bad_end;
2233    }
2234    if (!__bld_expnode()) goto bad_end;
2235    __get_vtok();
2236   }
2237 
2238 bad_end:
2239  /* replace entire expression with 1 bit x - not op empty */
2240  __set_xtab_errval();
2241  return(FALSE);
2242 }
2243 
2244 /*
2245  * ver 2001 #(list of param decls) form format collect param rhs expr
2246  *
2247  * expects 1st token of assignment rhs expr to have been read
2248  * and reads one past end , or )
2249  *
2250  * for mismatched nesting parse will catch error
2251  */
__col_lofp_paramrhsexpr(void)2252 extern int32 __col_lofp_paramrhsexpr(void)
2253 {
2254  int32 parlevel, catlevel;
2255  struct expr_t *ndp;
2256 
2257  __last_xtk = -1;
2258  ndp = __alloc_exprnd();
2259  ndp->optyp = LPAR;
2260  for (parlevel = 0, catlevel = 0;;)
2261   {
2262    switch ((byte) __toktyp) {
2263     case LPAR: parlevel++; break;
2264     case LCB: catlevel++; break;
2265     case RCB: catlevel--; break;
2266     case RPAR:
2267      if (parlevel <= 0 && catlevel <= 0) goto chk_empty;
2268      else parlevel--;
2269      break;
2270     case COMMA:
2271      if (parlevel <= 0 && catlevel <= 0)
2272       {
2273 chk_empty:
2274        /* empty = ) form illegal */
2275        if (__last_xtk == -1)
2276         {
2277          __pv_ferr(1106, "right hand side expression missing");
2278          goto bad_end;
2279         }
2280        ndp = __alloc_exprnd();
2281        ndp->optyp = RPAR;
2282        return(TRUE);
2283       }
2284      break;
2285     case TEOF: case SEMI:
2286      if (__pv_err_cnt <= __saverr_cnt)
2287       __pv_ferr(1093,
2288        "illegal token %s in parameter right hand side expression",
2289        __prt_vtok());
2290      goto bad_end;
2291    }
2292    if (!__bld_expnode()) goto bad_end;
2293    __get_vtok();
2294   }
2295 
2296 bad_end:
2297  /* replace entire expression with 1 bit x - not op empty */
2298  __set_xtab_errval();
2299  return(FALSE);
2300 }
2301 
2302 /*
2303  * collect an lvalue (all but procedural assign lhs)
2304  * expects 1st token of assignment lhs expr to have been read and reads
2305  * trailing =
2306  *
2307  * must emit error on 1st extra right parenthesis or will get error line
2308  * wrong - also if returns F must emit error
2309  */
__col_lval(void)2310 extern int32 __col_lval(void)
2311 {
2312  int32 parlevel;
2313 
2314  parlevel = 0;
2315  for (__last_xtk = -1;;)
2316   {
2317    switch ((byte) __toktyp) {
2318     case TEOF: case SEMI:
2319      {
2320 maybe_err:
2321       __pv_ferr(1094,
2322        "illegal token %s in lvalue - probable missing = or assign to function call",
2323        __prt_vtok());
2324       goto bad_end;
2325      }
2326     case EQ:
2327      if (__last_xtk == -1)
2328       {
2329        /* empty = ; form illegal */
2330        __pv_ferr(1096, "assignment lvalue missing");
2331        goto bad_end;
2332       }
2333      return(TRUE);
2334     case LPAR: parlevel++; break;
2335     case RPAR:
2336      if (--parlevel < 0) goto maybe_err;
2337      break;
2338    }
2339    if (!__bld_expnode()) goto bad_end;
2340    __get_vtok();
2341   }
2342 
2343 bad_end:
2344  __set_xtab_errval();
2345  return(FALSE);
2346 }
2347 
2348 /*
2349  * collect a procedural assignment lvalue (can end with <= non blocking
2350  * procedural assignment symbol or ( for task enable)
2351  *
2352  * expects 1st token of assignment lhs expr to have been read and reads
2353  * trailing '(' or ';' (no argumnet form), or '=' or '<=' for assign
2354  */
col2_lval(void)2355 static int32 col2_lval(void)
2356 {
2357  int32 sblevel, cblevel;
2358 
2359  sblevel = cblevel = 0;
2360  /* set flag for bld expnode error recovery - must be off when done */
2361  __expr_is_lval = TRUE;
2362  for (__last_xtk = -1;;)
2363   {
2364    switch ((byte) __toktyp) {
2365     case TEOF:
2366      if (__pv_err_cnt <= __saverr_cnt)
2367       __pv_ferr(1099,
2368        "illegal token %s in procedural assign lvalue or task enable",
2369         __prt_vtok());
2370      goto bad_end;
2371     case EQ:
2372      /* = can not appear in lhs because relational never '=' */
2373 chk_emp:
2374      if (__last_xtk == -1)
2375       {
2376        /* empty lhs "= <rhs side>" form illegal */
2377        __pv_ferr(1117, "empty assignment or task enable lvalue illegal");
2378        goto bad_end;
2379       }
2380      __expr_is_lval = FALSE;
2381      return(TRUE);
2382     case SEMI:
2383      /* no argument task enable "$stop;" - must not be empty */
2384      /* ; is error correction marker - can not be nested in anything */
2385      goto chk_emp;
2386     case RELLE:
2387      if (sblevel == 0 && cblevel == 0) goto chk_emp;
2388      break;
2389     case LPAR:
2390      if (sblevel == 0 && cblevel == 0) goto chk_emp;
2391      break;
2392     case LSB: sblevel++; break;
2393     case RSB: sblevel--; break;
2394     case LCB: cblevel++; break;
2395     case RCB: cblevel--; break;
2396    }
2397    if (!__bld_expnode()) goto bad_end;
2398    __get_vtok();
2399   }
2400 
2401 bad_end:
2402  __expr_is_lval = FALSE;
2403  __set_xtab_errval();
2404  return(FALSE);
2405 }
2406 
2407 /*
2408  * read a case expression list that ends with : or ,
2409  * also reads DEFAULT and ENDCASE expressions
2410  * expects 1st token to be read and reads ending token
2411  * but it is not included
2412  */
__col_caseexpr(void)2413 extern int32 __col_caseexpr(void)
2414 {
2415  int32 parlevel, collevel, sblevel, cblevel;
2416 
2417  parlevel = collevel = sblevel = cblevel = 0;
2418  for (__last_xtk = -1;;)
2419   {
2420    switch ((byte) __toktyp) {
2421     case QUEST: collevel++; break;
2422     case COLON:
2423      /* ? token must be followed by : for ?: expression */
2424      if (collevel > 0) collevel--;
2425      else if (sblevel <= 0) goto good_end;
2426      break;
2427     case LSB: sblevel++; break;
2428     case RSB: sblevel--; break;
2429     case LCB: cblevel++; break;
2430     case RCB: cblevel--; break;
2431     case LPAR: parlevel++; break;
2432     case RPAR: parlevel--; break;
2433     case COMMA:
2434      if (parlevel <= 0 && cblevel <= 0) goto good_end;
2435      break;
2436     case TEOF:
2437     case SEMI:
2438      if (__pv_err_cnt <= __saverr_cnt)
2439       __pv_ferr(1101, "illegal token %s in case item expression",
2440        __prt_vtok());
2441 bad_end:
2442      __set_xtab_errval();
2443      return(FALSE);
2444    }
2445    if (!__bld_expnode()) goto bad_end;
2446    __get_vtok();
2447   }
2448 good_end:
2449  if (__last_xtk == -1)
2450   {
2451    /* empty form illegal */
2452    __pv_ferr(1098, "case expression list missing");
2453    goto bad_end;
2454   }
2455  return(TRUE);
2456 }
2457 
2458 /*
2459  * build an expression tree node from current token
2460  * always places it in next free place in __exprtab
2461  * reuses storage so bld_xtree must allocate nodes
2462  *
2463  * puts ID name in expr_idtab that is changed to symbol in
2464  * parse term routine (either ID or xmr component)
2465  *
2466  * 'or' in expression always evor
2467  * anything part of expression goes through here
2468  */
__bld_expnode(void)2469 extern int32 __bld_expnode(void)
2470 {
2471  int32 wlen;
2472  struct opinfo_t *oip;
2473  struct expr_t *ndp;
2474 
2475  ndp = __alloc_exprnd();
2476  switch ((byte) __toktyp) {
2477   case ID:
2478    /* if can be inst. ref, assume global fix later */
2479    /* notice anthing in this case but id and glb wrong - caught later */
2480    if (strcmp(__token, "or") == 0) { ndp->optyp = OPEVOR; break; }
2481    ndp->optyp = ID;
2482    __alloc_expridnd(__token);
2483    break;
2484   case POSEDGE:
2485    ndp->optyp = OPPOSEDGE;
2486    break;
2487   case NEGEDGE:
2488    ndp->optyp = OPNEGEDGE;
2489    break;
2490   case OPEVCOMMAOR:
2491    ndp->optyp = OPEVCOMMAOR;
2492    break;
2493   case NUMBER:
2494    /* notice scanner only returns number */
2495    ndp->optyp = NUMBER;
2496    ndp->szu.xclen = __itoklen;
2497    if (__itoksized) ndp->unsiznum = FALSE; else ndp->unsiznum = TRUE;
2498 
2499    /* only true for decimal without 'd even 'd[num] is word32 */
2500    /* SJM 10/02/03 - scanner sets if signed - depends on new 2001 LRM rules */
2501    if (__itok_signed) ndp->has_sign = TRUE;
2502 
2503    ndp->ibase = (word32) __itokbase;
2504    ndp->sizdflt = (__itoksizdflt) ? TRUE : FALSE;
2505    /* Verilog values are really word32 bit patterns */
2506 
2507    wlen = wlen_(__itoklen);
2508    if (__itoklen <= WBITS)
2509     {
2510      /* always sets value - if not sharable uses non sharable alloc cval */
2511      ndp->ru.xvi = __alloc_shareable_cval(__acwrk[0], __bcwrk[0], __itoklen);
2512     }
2513    else
2514     {
2515      ndp->ru.xvi = __allocfill_cval_new(__acwrk, __bcwrk, wlen);
2516     }
2517    break;
2518   case REALNUM:
2519    /* num storage pted to by a part - usually (except xstk) no b part */
2520    ndp->optyp = REALNUM;
2521    ndp->szu.xclen = REALBITS;
2522    ndp->ibase = BDBLE;
2523    ndp->is_real = TRUE;
2524    ndp->has_sign = TRUE;
2525    /* LOOKATME - SIZE assuming size of real is 8 bytes here */
2526    ndp->ru.xvi = __alloc_shareable_rlcval(__itok_realval);
2527    break;
2528   case LITSTR:
2529    /* string copied to alloced storage and filled */
2530    ndp->optyp = NUMBER;
2531    ndp->szu.xclen = __itoklen;
2532 
2533    wlen = wlen_(__itoklen);
2534    ndp->ru.xvi = __allocfill_cval_new(__acwrk, __bcwrk, wlen);
2535    ndp->is_string = TRUE;
2536    ndp->unsiznum = FALSE;
2537    ndp->has_sign = FALSE;
2538    break;
2539   case TEOF:
2540    /* since no error recovery in interactive - this is finish path */
2541    /* caller sets to error expression */
2542    ndp->optyp = BADOBJ;
2543    return(FALSE);
2544   default:
2545    if (__toktyp > LASTOP)
2546     {
2547      /* keywords can not be in or end expressions */
2548      if (__pv_err_cnt <= __saverr_cnt)
2549       __pv_ferr(1104,
2550        "illegal token %s in expression - probable missing semicolon",
2551        __prt_vtok());
2552      return(FALSE);
2553     }
2554    /* build an operator node */
2555    oip = &(__opinfo[__toktyp]);
2556    if (oip->opclass == NOTANOP)
2557     {
2558      if (__pv_err_cnt <= __saverr_cnt)
2559       __pv_ferr(1105, "illegal punctuation %s in expression",
2560       __prt_vtok());
2561      return(FALSE);
2562     }
2563    /* build an operator node */
2564    ndp->optyp = __toktyp;
2565   }
2566  return(TRUE);
2567 }
2568 
2569 #define HASHTABSIZ 3011     /* prime number size of consts hash table */
2570 #define HASHSEED 0x371546dc    /* seed of first word of the hash table */
2571 
2572 
2573 /*
2574  * setup the constant tables
2575  *
2576  * allocate design wide constant table - so fixed constants at bottom
2577  * BEWARE - since constant table is design and reallocated must always ndx
2578  * allocate initial small constant table - grows when needed
2579  */
__setup_contab(void)2580 extern void __setup_contab(void)
2581 {
2582  register int32 i, j;
2583 
2584  __contabwsiz = 400;
2585  __contab = (word32 *) __my_malloc(__contabwsiz*sizeof(word32));
2586  /* 0th and 1st unused - marker to catch errors */
2587  for (i = 0; i < 4; i++) __contab[i] = ALL1W;
2588  /* 3rd is one bit z */
2589  __contab[4] = 0;
2590  __contab[5] = 1;
2591  /* 4th is 1 bit x */
2592  __contab[6] = 1;
2593  __contab[7] = 1;
2594  /* 5th is 32 bit z */
2595  __contab[8] = 0;
2596  __contab[9] = ALL1W;
2597  /* 6th is 32 bit x */
2598  __contab[10] = ALL1W;
2599  __contab[11] = ALL1W;
2600 
2601  for (i = 12, j = 0; i <= 12 + 2*128; i += 2, j++)
2602   {
2603    __contab[i] = j;
2604    __contab[i + 1] = 0;
2605   }
2606  /* also need build in special contab index for opempty */
2607  /* all rhs igen expr eval OP EMPTY nodes point to this */
2608  __opempty_contabi = 270;
2609  __contab[270] = ' ';
2610  __contab[271] = 0;
2611  __contabwi = 272;
2612 
2613  __contab_hash = (struct contab_info_t **)
2614   __my_malloc(HASHTABSIZ*sizeof(struct contab_info_t *));
2615  memset(__contab_hash, 0, HASHTABSIZ*sizeof(struct contab_info_t *));
2616 
2617 }
2618 
2619 /* some local use only constant for fixed con table locations */
2620 #define FIXCON_1BITZ 4
2621 #define FIXCON_1BITX 6
2622 #define FIXCON_32BITZ 8
2623 #define FIXCON_32BITX 10
2624 #define NONXZ_CONBASE 12
2625 
2626 /*
2627  * sharable (non IS form) any 32 bit or any 32 or less 0
2628  * plus some non x/z low values
2629  */
__alloc_shareable_cval(word32 aval,word32 bval,int32 bwid)2630 extern int32 __alloc_shareable_cval(word32 aval, word32 bval, int32 bwid)
2631 {
2632  int32 wi;
2633 
2634  if (bwid == 1)
2635   {
2636    if (bval == 0) goto do_nonxz;
2637    if (aval == 0) return(FIXCON_1BITZ);
2638    return(FIXCON_1BITX);
2639   }
2640 
2641  if (bval == ALL1W)
2642   {
2643    if (bwid != WBITS) goto do_alloc;
2644    if (aval == 0) return(FIXCON_32BITZ);
2645    if (aval == ALL1W) return(FIXCON_32BITX);
2646    goto do_alloc;
2647   }
2648  if (bval != 0) goto do_alloc;
2649 do_nonxz:
2650  if (aval <= 128) return(NONXZ_CONBASE + 2*aval);
2651 
2652 do_alloc:
2653  aval &= __masktab[bwid];
2654  bval &= __masktab[bwid];
2655  wi = __allocfill_cval_new(&(aval), &(bval), 1);
2656  return(wi);
2657 }
2658 
2659 /*
2660  * allocate a constant value in design wide constant table
2661  *
2662  * now only for IS forms where must allocate big region and can't use
2663  * hashing to share because each inst must be filled with mem copy
2664  *
2665  * wlen is really wlen times no. of instances in IS form - multiply by
2666  * 2 works since need b parts for each inst
2667  * know a and b parts contiguous
2668  */
__alloc_is_cval(int32 wlen)2669 extern int32 __alloc_is_cval(int32 wlen)
2670 {
2671  int32 wi;
2672 
2673  if (__contabwi + 2*wlen >= __contabwsiz) __grow_contab(2*wlen);
2674  wi = __contabwi;
2675  __contabwi += 2*wlen;
2676  return(wi);
2677 }
2678 
2679 /*
2680  * sharable (non IS form) for real constants
2681  * SJM 05/03/05 - now reals go into hashed part of contab
2682  */
__alloc_shareable_rlcval(double d1)2683 extern int32 __alloc_shareable_rlcval(double d1)
2684 {
2685  int32 wi;
2686  word32 rword[2];
2687 
2688  memcpy(&(rword), &(d1), sizeof(double));
2689  /* notice word length is 1 since reals have no b part */
2690  wi = __allocfill_cval_new(&(rword[0]), &(rword[1]), 1);
2691  return(wi);
2692 }
2693 
2694 /*
2695  * new version of allocate a constant value in design wide constant table
2696  * notice passing word len but need room for 2*wlen for b part
2697  *
2698  * that uses hashing to prevent too much growth of contab during
2699  * non blocking assign realloc and also just a better algorithm
2700  */
__allocfill_cval_new(word32 * ap,word32 * bp,int32 wlen)2701 extern int32 __allocfill_cval_new(word32 *ap, word32 *bp, int32 wlen)
2702 {
2703  register word32 hti;
2704  register struct contab_info_t *cip;
2705  int32 wi, bytsiz;
2706  word32 *wp;
2707 
2708  hti = get_hash(ap, bp, wlen);
2709  bytsiz = wlen*WRDBYTES;
2710  if ((cip = __contab_hash[hti]) != NULL)
2711   {
2712    for (; cip != NULL; cip = cip->cnxt)
2713     {
2714      if (cip->cwid != wlen) continue;
2715 
2716      wp = &(__contab[cip->xvi]);
2717      if (memcmp(wp, ap, bytsiz) == 0 && memcmp(&(wp[wlen]), bp, bytsiz) == 0)
2718        return(cip->xvi);
2719     }
2720   }
2721 
2722  if (__contabwi + 2*wlen >= __contabwsiz) __grow_contab(2*wlen);
2723  wi = __contabwi;
2724  __contabwi += 2*wlen;
2725  memcpy(&(__contab[wi]), ap, bytsiz);
2726  memcpy(&(__contab[wi + wlen]), bp, bytsiz);
2727 
2728  cip = (struct contab_info_t *) __my_malloc(sizeof(struct contab_info_t));
2729  cip->xvi = wi;
2730  cip->cwid = wlen;
2731  /* put on front */
2732  cip->cnxt = __contab_hash[hti];
2733  __contab_hash[hti] = cip;
2734  return(wi);
2735 }
2736 
2737 /*
2738  * hash function
2739  */
get_hash(word32 * ap,word32 * bp,int32 wlen)2740 static word32 get_hash(word32 *ap, word32 *bp, int32 wlen)
2741 {
2742  register int32 wi;
2743  word32 hval;
2744 
2745  hval = ap[0] * HASHSEED;
2746  for (wi = 1; wi < wlen; wi++)
2747   {
2748    hval ^= (ap[wi] ^ bp[wi]);
2749   }
2750  hval += wlen;
2751  return(hval % HASHTABSIZ);
2752 }
2753 
2754 /*
2755  * grow design wide constant table
2756  *
2757  * when growing, grow with current needed words in case IS array large
2758  * all sizes are in words because need word32 alignment
2759  */
__grow_contab(int32 ndwrds)2760 extern void __grow_contab(int32 ndwrds)
2761 {
2762  int32 old_ctabsiz, obsize, nbsize;
2763 
2764  old_ctabsiz = __contabwsiz;
2765  obsize = __contabwsiz*sizeof(word32);
2766  /* fibronacci growth */
2767  __contabwsiz = 3*(old_ctabsiz + ndwrds)/2;
2768  nbsize = __contabwsiz*sizeof(word32);
2769  __contab = (word32 *) __my_realloc((char *) __contab, obsize, nbsize);
2770 }
2771 
2772 
2773 /*
2774  * EXPRESSION PROCESSING CODE
2775  */
2776 
2777 /*
2778  * operator table
2779  * SPECOP means requires separate case entry and special processing
2780  * BEWARE - this table requires operator number k to be on row k
2781  */
2782 struct opinfo_t __opinfo[] = {
2783  /* place holders since using token number used as index into op table */
2784  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "00E" },
2785  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "idE" },
2786  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "bnE" },
2787  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "nE" },
2788  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "inE" },
2789  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rE" },
2790  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "irE" },
2791  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "sE" },
2792  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "giE" },
2793  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" },
2794  /* 10 */
2795  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" },
2796  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" },
2797  /* notice ; now 12 */
2798  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, ";" },
2799  { SPECOP, NOTREALOP, NOTPTHOP, WIDSUM, "," },
2800  { SPECOP, NOTREALOP, PTHOP, WIDNONE, ":" },
2801  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "#" },
2802  /* left grouping operators treated specially */
2803  { BINOP, NOTREALOP, NOTPTHOP, WIDNONE, "(" },  /* ( function call op. */
2804  { SPECOP, NOTREALOP, PTHOP, WIDNONE, ")" },    /* ) RPAR */
2805  { SPECOP, NOTREALOP, PTHOP, WIDNONE, "[" },    /* [ LSB */
2806  { SPECOP, NOTREALOP, PTHOP, WIDNONE, "]" },    /* ] RSB */
2807  /* 20 */
2808  { BINOP, NOTREALOP, PTHOP, WIDSUM, "{" },      /* { LCB - empty rght but bin */
2809  { SPECOP, NOTREALOP, PTHOP, WIDNONE, "}" },    /* } RCB */
2810  { SPECOP, NOTREALOP, PTHOP, WIDNONE, "." },    /* . DOT */
2811  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "@" },
2812  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "->" },
2813  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "=" },
2814  /* unary ops */
2815  /* LOOKATME - this is not really self determined result context determines */
2816  /* but does not fit in pattern so always checked for */
2817  { UNOP, NOTREALOP, PTHOP, WIDMAX, "~" },       /* ~ BITNOT - self determine */
2818  { UNOP, REALOP, PTHOP, WIDONE, "!" },          /* ! NOT */
2819  { RUNOP, REALOP, NOTPTHOP, WIDONE, "!" },      /* ! REALNOT */
2820  /* both unary and binary */
2821  { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "^~" },    /* REDXNOR - must be ^~ */
2822  /* 30 */
2823  { BOTHOP, REALOP, NOTPTHOP, WIDMAX, "+" },     /* + PLUS */
2824  { BOTHOP, REALOP, NOTPTHOP, WIDMAX, "-" },     /* - MINUS (un fixed to self)*/
2825  { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "&" },     /* & BITREDAND */
2826  { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "|" },     /* | BITREDOR */
2827  { BOTHOP, NOTREALOP, PTHOP, WIDMAX, "^" },     /* ^ BITREDXOR */
2828  { RBOTHOP, REALOP, NOTPTHOP, WIDMAX, "-" },     /* + REALINUS */
2829  /* binary operators */
2830  { BINOP, REALOP, NOTPTHOP, WIDMAX, "*" },      /* * TIMES */
2831  { BINOP, REALOP, NOTPTHOP, WIDMAX, "/" },      /* / DIV */
2832  { BINOP, NOTREALOP, NOTPTHOP, WIDMAX, "%" },   /* % MOD */
2833  { BINOP, REALOP, NOTPTHOP, WIDENONE, ">=" },   /* >= RELGE */
2834  /* 40 */
2835  { BINOP, REALOP, NOTPTHOP, WIDENONE, ">" },    /* > RELGT */
2836  { BINOP, REALOP, NOTPTHOP, WIDENONE, "<=" },   /* <= RELLE (not assgn) */
2837  { BINOP, REALOP, NOTPTHOP, WIDENONE, "<" },    /* < RELLT */
2838  { BINOP, NOTREALOP, NOTPTHOP, WIDENONE, "===" }, /* === RELCEQ */
2839  { BINOP, REALOP, PTHOP, WIDENONE, "==" },      /* == RELEQ */
2840  { BINOP, NOTREALOP, NOTPTHOP, WIDENONE, "!==" }, /* !== RELCNEQ */
2841  { BINOP, REALOP, PTHOP, WIDENONE, "!=" },      /* != RELNEQ */
2842  { BINOP, REALOP, PTHOP, WIDONE, "&&" },        /* && BOOLAND */
2843  { BINOP, REALOP, PTHOP, WIDONE, "||" },        /* || BOOLOR */
2844  { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, "<<" }, /* << SHIFTL */
2845  /* 50 */
2846  { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, "<<<" }, /* <<< ASHIFTL */
2847  { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, ">>" }, /* >> SHIFTR */
2848  { BINOP, NOTREALOP, NOTPTHOP, WIDLEFT, ">>>" }, /* >>> ASHIFTR */
2849  { BINOP, NOTREALOP, NOTPTHOP, WIDONE, "*>" },  /* *> FPTHCON */
2850  { BINOP, NOTREALOP, NOTPTHOP, WIDONE, "=>" },  /* => PPTHCON */
2851  { BINOP, NOTREALOP, NOTPTHOP, WIDONE, "&&&" }, /* TCHK &&& (cond. event) */
2852  { RBINOP, REALOP, NOTPTHOP, WIDMAX, "+" },     /* + REALPLUS */
2853  { RBINOP, REALOP, NOTPTHOP, WIDMAX, "*" },     /* * REALTIMES */
2854  { RBINOP, REALOP, NOTPTHOP, WIDMAX, "/" },     /* / REALDIV */
2855  { RBINOP, REALOP, NOTPTHOP, WIDENONE, ">" },   /* > REALRELGT */
2856  /* 60 */
2857  { RBINOP, REALOP, NOTPTHOP, WIDENONE, ">=" },  /* >= REALRELGE */
2858  { RBINOP, REALOP, NOTPTHOP, WIDENONE, "<" },   /* < REALRELLT */
2859  { RBINOP, REALOP, NOTPTHOP, WIDENONE, "<=" },  /* <= REALRELLE */
2860  { RBINOP, REALOP, NOTPTHOP, WIDENONE, "==" },  /* == REALRELEQ */
2861  { RBINOP, REALOP, NOTPTHOP, WIDENONE, "!=" },  /* != REALRELEQ */
2862  { RBINOP, REALOP, NOTPTHOP, WIDONE, "&&" },    /* && REALBOOLAND */
2863  { RBINOP, REALOP, NOTPTHOP, WIDONE, "||" },    /* != REALBOOLOR */
2864  /* tree will be left of : will be (cond)?(1st expr) and right will be */
2865  /* 2nd must be fixed, need for a[x?y:z:...] */
2866  /* width is max of operators (i.e. narrow must be padded) */
2867  { SPECOP, REALOP, PTHOP, WIDMAX, "?" },        /* ? QUEST (lhs part of ?:) */
2868  { SPECOP, NOTREALOP, PTHOP, WIDMAX, "?:" },    /* : QCOL (rhs part of ?:)  */
2869  { SPECOP, NOTREALOP, PTHOP, WIDSELF, "PARTSEL" },/* [ PARTSEL (2 val sel) */
2870  /* 70 */
2871  { BINOP, NOTREALOP, PTHOP, WIDSUM, "CATCOMMA" }, /* , part of { } */
2872  /* probably should have real quad op. for these */
2873  { BINOP, NOTREALOP, PTHOP, WIDSELF, "CATREP" },  /* [num]{ } concat repeat */
2874  { BINOP, NOTREALOP, NOTPTHOP, WIDSELF, "FCALL OP" }, /* function call */
2875  { BINOP, NOTREALOP, NOTPTHOP, WIDSELF, "LIST COMMA" },/* , of fcall () list*/
2876  /* only legal in event expressions */
2877  { SPECOP, NOTREALOP, NOTPTHOP, WIDONE, "or" },   /* OR event or */
2878  { SPECOP, NOTREALOP, NOTPTHOP, WIDONE, "," },    /* , event or as comma */
2879  /* these are normal unaries except semantics only operand of evor */
2880  { UNOP, NOTREALOP, NOTPTHOP, WIDONE, "posedge " }, /* OPPOSEDGE ev prefix */
2881  { UNOP, NOTREALOP, NOTPTHOP, WIDONE, "negedge " }, /* OPNEGEDGE ev prefix */
2882  /* this do not use table - handle in code */
2883  { SPECOP, REALOP, NOTPTHOP, WIDMAX, "?" },     /* REALREALQUEST (lhs of ?:) */
2884  { SPECOP, REALOP, NOTPTHOP, WIDMAX, "?" },     /* REALREGQUEST (lhs of ?:) */
2885  /* 80 */
2886  { SPECOP, REALOP, NOTPTHOP, WIDMAX, "?:" },    /* REGREALQCOL (rhs of ?:) */
2887  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" }, /* GLBREF */
2888  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "rmE" }, /* GLBPATH */
2889  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "XMR ID" }, /* XMRID */
2890  { BINOP, NOTREALOP, NOTPTHOP, WIDSELF, "XMR LIST COMMA" },/* XMR comma */
2891  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "EXPR END" },
2892  { NOTANOP, NOTREALOP, NOTPTHOP, WIDNONE, "TEOF" },
2893 };
2894 
2895 /*
2896  * convert expression table to expression tree
2897  * for specparam may start at 1 instead of 0 if not min:typ:max form
2898  */
__bld_xtree(int32 start_xndi)2899 extern void __bld_xtree(int32 start_xndi)
2900 {
2901  struct expr_t *ndp;
2902 
2903  /* add end of expression fence */
2904  __has_top_mtm = FALSE;
2905  ndp = __alloc_exprnd();
2906  ndp->optyp = UNDEF;
2907  __xndi = start_xndi;
2908  __saverr_cnt = __pv_err_cnt;
2909  /* __xndi should point to last token which is added UNDEF fence */
2910  if ((__root_ndp = parse_qcexpr()) == NULL || __xndi != __last_xtk)
2911   {
2912    /* if for some reason, empty exprs (no error), emit some kind of err */
2913    if (__saverr_cnt == __pv_err_cnt)
2914     {
2915      if (__xndi > __last_xtk)
2916       __pv_ferr(1108, "expression missing required operator or operand");
2917      else if (__xndi < __last_xtk)
2918       {
2919        if (__exprtab[__xndi]->optyp == COMMA)
2920         __pv_ferr(1111,
2921          "expression list illegal - check for missing ')' or extra ','");
2922        else __pv_ferr(1109, "expression illegal token [%s]",
2923         to_xndnam(__xs, __xndi));
2924       }
2925      else
2926       {
2927        __pv_ferr(1110, "expression parse error at token [%s]",
2928 	to_xndnam(__xs, __xndi));
2929       }
2930     }
2931    /* notice by here already moved to allocated nodes from exprtab */
2932    __root_ndp = __alloc_newxnd();
2933    __set_numval(__root_ndp, 1L, 1L, 1);
2934   }
2935 }
2936 
2937 /*
2938  * EXPRESSION PARSING ROUTINES
2939  */
2940 
2941 /*
2942  * parse an expression that can contain ?: operators
2943  *
2944  * ?: is lowest precedence - everything has stronger attraction
2945  */
parse_qcexpr(void)2946 static struct expr_t *parse_qcexpr(void)
2947 {
2948  struct expr_t *ndp, *qcndp, *tndp, *fndp;
2949 
2950  /* handle most common cases without parsing */
2951  /* before parsing bld xtree always places end marker - undef at end */
2952  /* so last xtk here is one past end i.e. 1 for ID */
2953  /* also because not yet parsed part select operator still LSB */
2954  if (__last_xtk == 1
2955   || (__last_xtk == 3 && __exprtab[1]->optyp == LSB)
2956   || (__last_xtk == 6 && __exprtab[1]->optyp == LSB
2957      && __exprtab[3]->optyp == COLON))
2958   {
2959    qcndp = parse_term();
2960    return(qcndp);
2961   }
2962 
2963  /* DBG need special case code, just set __last_xtk == 1 term */
2964  /* routine leaves __xndi at next place to look */
2965  if ((qcndp = parse_boolorop()) == NULL) return(NULL);
2966  ndp = __exprtab[__xndi];
2967  if (ndp->optyp == QUEST)
2968   {
2969    ndp = alloc_xtnd(__xndi);
2970    ndp->lu.x = qcndp;
2971    qcndp = ndp;
2972    __xndi++;
2973    /* this can be recursive since no left recursion problem for ?: */
2974    /* this forces right to left grouping since reduces right then backs */
2975    /* up recursion tree to build reduced pieces from left */
2976    if ((tndp = parse_qcexpr()) == NULL)
2977     {
2978 bad_qcexpr:
2979      if (__pv_err_cnt <= __saverr_cnt)
2980       __pv_ferr(1112, "?: parse error at token [%s]", to_xndnam(__xs,
2981        __xndi));
2982      /* move x ndi to end */
2983      xskip_toend();
2984 
2985      /* on error here make a 1 bit x this is part of longer expr. */
2986      ndp = alloc_xtnd(__xndi);
2987      __set_numval(ndp, 1L, 1L, 1);
2988      return(ndp);
2989     }
2990    ndp = __exprtab[__xndi];
2991    if (ndp->optyp != COLON) goto bad_qcexpr;
2992    ndp = alloc_xtnd(__xndi);
2993    ndp->optyp = QCOL;
2994    qcndp->ru.x = ndp;
2995    ndp->lu.x = tndp;
2996    __xndi++;
2997    if ((fndp = parse_qcexpr()) == NULL) goto bad_qcexpr;
2998    ndp->ru.x = fndp;
2999   }
3000  return(qcndp);
3001 }
3002 
3003 /*
3004  * skip past 1 expression node of node type ndtyp
3005  * this is needed
3006  */
xskip_toend(void)3007 static void xskip_toend(void)
3008 {
3009  struct expr_t *ndp;
3010 
3011  for (;;__xndi++)
3012   {
3013    /* never skip past expr. ending fence */
3014    ndp = __exprtab[__xndi];
3015    if (ndp->optyp == UNDEF) break;
3016   }
3017 }
3018 
3019 /*
3020  * parse boolean or (||) operators
3021  * precdence one up from lowest
3022  */
parse_boolorop(void)3023 static struct expr_t *parse_boolorop(void)
3024 {
3025  int32 savi;
3026  struct expr_t *ndp, *rhsndp, *leftopndp;
3027 
3028  /* routine leaves __xndi at next place to look */
3029  if ((leftopndp = parse_boolandop()) == NULL) return(NULL);
3030  ndp = __exprtab[__xndi];
3031  for (;;)
3032   {
3033    if (ndp->optyp == BOOLOR)
3034     {
3035      savi = __xndi;
3036      __xndi++;
3037      /* treat [term [op] error] as term - could improve recovery here */
3038      if ((rhsndp = parse_boolandop()) == NULL) break;
3039      /* this makes sure optyp right */
3040      ndp = alloc_xtnd(savi);
3041      ndp->lu.x = leftopndp;
3042      ndp->ru.x = rhsndp;
3043      leftopndp = ndp;
3044      ndp = __exprtab[__xndi];
3045     }
3046    else break;
3047   }
3048  return(leftopndp);
3049 }
3050 
3051 /*
3052  * parse boolean and (&&) operators
3053  */
parse_boolandop(void)3054 static struct expr_t *parse_boolandop(void)
3055 {
3056  int32 savi;
3057  struct expr_t *ndp, *rhsndp, *leftopndp;
3058 
3059  /* routine leaves __xndi at next place to look */
3060  if ((leftopndp = parse_borop()) == NULL) return(NULL);
3061  ndp = __exprtab[__xndi];
3062  for (;;)
3063   {
3064    if (ndp->optyp == BOOLAND)
3065     {
3066      savi = __xndi;
3067      __xndi++;
3068      if ((rhsndp = parse_borop()) == NULL) break;
3069 
3070      /* this makes sure optyp right */
3071      ndp = alloc_xtnd(savi);
3072      ndp->lu.x = leftopndp;
3073      ndp->ru.x = rhsndp;
3074      leftopndp = ndp;
3075      ndp = __exprtab[__xndi];
3076     }
3077    else break;
3078   }
3079  return(leftopndp);
3080 }
3081 
3082 /*
3083  * parse bit wise or operators
3084  */
parse_borop(void)3085 static struct expr_t *parse_borop(void)
3086 {
3087  int32 savi;
3088  struct expr_t *ndp, *rhsndp, *leftopndp;
3089 
3090  /* routine leaves __xndi at next place to look */
3091  if ((leftopndp = parse_bxorop()) == NULL) return(NULL);
3092  ndp = __exprtab[__xndi];
3093  for (;;)
3094   {
3095    if (ndp->optyp == BITREDOR)
3096     {
3097      /* fence and must check at binary bit wise | for following un red | */
3098      if (__exprtab[__xndi + 1]->optyp == BITREDOR)
3099       {
3100        __pv_fwarn(564,
3101 	"[expr] | |[expr] invalid - unary should be surrounded by parentheses");
3102       }
3103      savi = __xndi;
3104      __xndi++;
3105      if ((rhsndp = parse_bxorop()) == NULL) break;
3106      /* this makes sure optyp right */
3107      ndp = alloc_xtnd(savi);
3108      ndp->lu.x = leftopndp;
3109      ndp->ru.x = rhsndp;
3110      leftopndp = ndp;
3111      ndp = __exprtab[__xndi];
3112     }
3113    else break;
3114   }
3115  return(leftopndp);
3116 }
3117 
3118 /*
3119  * parse bit wise xor operators
3120  */
parse_bxorop(void)3121 static struct expr_t *parse_bxorop(void)
3122 {
3123  int32 savi;
3124  struct expr_t *ndp, *rhsndp, *leftopndp;
3125 
3126  /* routine leaves __xndi at next place to look */
3127  if ((leftopndp = parse_bandop()) == NULL) return(NULL);
3128  ndp = __exprtab[__xndi];
3129  for (;;)
3130   {
3131    if (ndp->optyp == BITREDXOR || ndp->optyp == REDXNOR)
3132     {
3133      savi = __xndi;
3134      __xndi++;
3135      /* treat [term [op] error] as term */
3136      if ((rhsndp = parse_bandop()) == NULL) break;
3137      /* this makes sure optyp right */
3138      ndp = alloc_xtnd(savi);
3139      ndp->lu.x = leftopndp;
3140      ndp->ru.x = rhsndp;
3141      leftopndp = ndp;
3142      ndp = __exprtab[__xndi];
3143     }
3144    else break;
3145   }
3146  return(leftopndp);
3147 }
3148 
3149 /*
3150  * parse bit wise and operators
3151  */
parse_bandop(void)3152 static struct expr_t *parse_bandop(void)
3153 {
3154  int32 savi;
3155  struct expr_t *ndp, *rhsndp, *leftopndp;
3156 
3157  /* routine leaves __xndi at next place to look */
3158  if ((leftopndp = parse_eqop()) == NULL) return(NULL);
3159  ndp = __exprtab[__xndi];
3160  for (;;)
3161   {
3162    if (ndp->optyp == BITREDAND)
3163     {
3164      /* notice when see binary & must see if following unary red. & */
3165      /* know fence always present */
3166      if (__exprtab[__xndi + 1]->optyp == BITREDAND)
3167       {
3168        __pv_fwarn(564,
3169 	"[expr] & &[expr] invalid - unary should be surrounded by parentheses");
3170       }
3171      savi = __xndi;
3172      __xndi++;
3173      if ((rhsndp = parse_eqop()) == NULL) break;
3174      /* this makes sure optyp right */
3175      ndp = alloc_xtnd(savi);
3176      ndp->lu.x = leftopndp;
3177      ndp->ru.x = rhsndp;
3178      leftopndp = ndp;
3179      ndp = __exprtab[__xndi];
3180     }
3181    else break;
3182   }
3183  return(leftopndp);
3184 }
3185 
3186 /*
3187  * parse equal not equal operators
3188  */
parse_eqop(void)3189 static struct expr_t *parse_eqop(void)
3190 {
3191  int32 savi;
3192  struct expr_t *ndp, *rhsndp, *leftopndp;
3193 
3194  /* routine leaves __xndi at next place to look */
3195  if ((leftopndp = parse_ltgtop()) == NULL) return(NULL);
3196  ndp = __exprtab[__xndi];
3197  for (;;)
3198   {
3199    if (ndp->optyp == RELEQ || ndp->optyp == RELNEQ || ndp->optyp == RELCEQ
3200     || ndp->optyp == RELCNEQ)
3201     {
3202      savi = __xndi;
3203      __xndi++;
3204      if ((rhsndp = parse_ltgtop()) == NULL) break;
3205      /* this makes sure optyp right */
3206      ndp = alloc_xtnd(savi);
3207      ndp->lu.x = leftopndp;
3208      ndp->ru.x = rhsndp;
3209      leftopndp = ndp;
3210      ndp = __exprtab[__xndi];
3211     }
3212    else break;
3213   }
3214  return(leftopndp);
3215 }
3216 
3217 /*
3218  * parse a less than or greater than type op
3219  */
parse_ltgtop(void)3220 static struct expr_t *parse_ltgtop(void)
3221 {
3222  int32 savi;
3223  struct expr_t *ndp, *rhsndp, *leftopndp;
3224 
3225  /* routine leaves __xndi at next place to look */
3226  if ((leftopndp = parse_shop()) == NULL) return(NULL);
3227  ndp = __exprtab[__xndi];
3228  for (;;)
3229   {
3230    if (ndp->optyp == RELLT || ndp->optyp == RELLE || ndp->optyp == RELGT
3231     || ndp->optyp == RELGE)
3232     {
3233      savi = __xndi;
3234      __xndi++;
3235      if ((rhsndp = parse_shop()) == NULL) break;
3236      /* this makes sure optyp right */
3237      ndp = alloc_xtnd(savi);
3238      ndp->lu.x = leftopndp;
3239      ndp->ru.x = rhsndp;
3240      leftopndp = ndp;
3241      ndp = __exprtab[__xndi];
3242     }
3243    else break;
3244   }
3245  return(leftopndp);
3246 }
3247 
3248 /*
3249  * parse a shift type op
3250  */
parse_shop(void)3251 static struct expr_t *parse_shop(void)
3252 {
3253  int32 savi;
3254  struct expr_t *ndp, *rhsndp, *leftopndp;
3255 
3256  /* routine leaves __xndi at next place to look */
3257  if ((leftopndp = parse_addop()) == NULL) return(NULL);
3258  ndp = __exprtab[__xndi];
3259  for (;;)
3260   {
3261    if (ndp->optyp == SHIFTL || ndp->optyp == SHIFTR
3262     || ndp->optyp == ASHIFTL || ndp->optyp == ASHIFTR)
3263     {
3264      savi = __xndi;
3265      __xndi++;
3266      if ((rhsndp = parse_addop()) == NULL) break;
3267      /* this makes sure optyp right */
3268      ndp = alloc_xtnd(savi);
3269      ndp->lu.x = leftopndp;
3270      ndp->ru.x = rhsndp;
3271      leftopndp = ndp;
3272      ndp = __exprtab[__xndi];
3273     }
3274    else break;
3275   }
3276  return(leftopndp);
3277 }
3278 
3279 /*
3280  * parse a add type op
3281  */
parse_addop(void)3282 static struct expr_t *parse_addop(void)
3283 {
3284  int32 savi;
3285  /* struct expr_t *ndp, *lhsndp, *rhsndp, *opndp, *last_opndp; */
3286  struct expr_t *ndp, *rhsndp, *leftopndp;
3287 
3288  /* routine leaves __xndi at next place to look */
3289  if ((leftopndp = parse_mulop()) == NULL) return(NULL);
3290  ndp = __exprtab[__xndi];
3291  /* last_opndp = NULL; */
3292  for (;;)
3293   {
3294    if (ndp->optyp == PLUS || ndp->optyp == MINUS)
3295     {
3296      savi = __xndi;
3297      __xndi++;
3298      if ((rhsndp = parse_mulop()) == NULL) break;
3299      /* this makes sure optyp right */
3300      ndp = alloc_xtnd(savi);
3301      ndp->lu.x = leftopndp;
3302      ndp->ru.x = rhsndp;
3303      leftopndp = ndp;
3304      ndp = __exprtab[__xndi];
3305     }
3306    else break;
3307   }
3308  return(leftopndp);
3309 }
3310 
3311 /*
3312  * parse a mult/div type op
3313  */
parse_mulop(void)3314 static struct expr_t *parse_mulop(void)
3315 {
3316  int32 savi;
3317  struct expr_t *ndp, *rhsndp, *leftopndp;
3318 
3319  /* routine leaves __xndi at next place to look */
3320  if ((leftopndp = parse_unopterm()) == NULL) return(NULL);
3321  ndp = __exprtab[__xndi];
3322  for (;;)
3323   {
3324    if (ndp->optyp == TIMES || ndp->optyp == DIV || ndp->optyp == MOD)
3325     {
3326      savi = __xndi;
3327      __xndi++;
3328      if ((rhsndp = parse_unopterm()) == NULL) break;
3329      /* this makes sure optyp right */
3330      ndp = alloc_xtnd(savi);
3331      ndp->lu.x = leftopndp;
3332      ndp->ru.x = rhsndp;
3333      leftopndp = ndp;
3334      ndp = __exprtab[__xndi];
3335     }
3336    else break;
3337   }
3338  return(leftopndp);
3339 }
3340 
3341 /*
3342  * parse [un. op] <term>
3343  * expects __xndi to point to next place in expr. and moves to 1 after end
3344  *
3345  * parens here surround subexpressions not fcall
3346  */
parse_unopterm(void)3347 static struct expr_t *parse_unopterm(void)
3348 {
3349  int32 sav_xndi;
3350  struct expr_t *ndp, *ndp2, *unopndp, *lastndp;
3351 
3352  lastndp = NULL;
3353  unopndp = NULL;
3354  ndp = __exprtab[__xndi];
3355  switch ((byte) ndp->optyp) {
3356   /* notice real number can not start with . (.33 illegal) */
3357   case ID: case NUMBER: case REALNUM: return(parse_term());
3358   case LPAR:
3359 do_parens:
3360    sav_xndi = __xndi++;
3361    if ((ndp2 = parse_qcexpr()) == NULL) return(NULL);
3362    ndp = __exprtab[__xndi];
3363    /* any time in ( expr. may be (expr:expr:expr) form */
3364    /* only parsable because all 3 required if : present */
3365    if (ndp->optyp == COLON)
3366     {
3367      struct expr_t *minxndp, *nomxndp;
3368 
3369      minxndp = ndp2;
3370      __xndi++;
3371      if ((ndp2 = parse_qcexpr()) == NULL)
3372       {
3373 mintyp_err:
3374        if (__pv_err_cnt <= __saverr_cnt)
3375         __pv_ferr(1113, "mintypmax expression error at token [%s]",
3376          to_xndnam(__xs, __xndi));
3377        /* must skip one past 3 value form ending ) */
3378        skip_3valend();
3379        return(NULL);
3380       }
3381      nomxndp = ndp2;
3382      ndp = __exprtab[__xndi];
3383      if (ndp->optyp != COLON) goto mintyp_err;
3384      __xndi++;
3385      if ((ndp2 = parse_qcexpr()) == NULL) goto mintyp_err;
3386      ndp = __exprtab[__xndi];
3387      if (ndp->optyp != RPAR) goto mintyp_err;
3388      if (__mintypmax_sel == DEL_MIN) ndp2 = minxndp;
3389      else if (__mintypmax_sel == DEL_TYP) ndp2 = nomxndp;
3390      __xndi++;
3391      if (sav_xndi == 0) __has_top_mtm = TRUE;
3392      goto unop_ret;
3393     }
3394    /* either eox or ) seen or will not get here */
3395    if (ndp->optyp != RPAR)
3396     {
3397      __pv_ferr(1113,
3398       "expression primary or mintypmax expression ending ) expected - %s read",
3399       to_xndnam(__xs, __xndi));
3400      return(NULL);
3401     }
3402    __xndi++;
3403    goto unop_ret;
3404  }
3405  if (is_unop(ndp->optyp))
3406   {
3407 rep_unops:
3408    if (ndp->optyp != PLUS)
3409     {
3410      ndp = alloc_xtnd(__xndi);
3411      ndp->ru.x = NULL;
3412      if (lastndp == NULL) unopndp = ndp; else lastndp->lu.x = ndp;
3413      lastndp = ndp;
3414     }
3415 
3416    ndp2 = __exprtab[++__xndi];
3417    if (ndp2->optyp == LPAR) goto do_parens;
3418    /* unary operator chain */
3419    if (is_unop(ndp2->optyp))
3420     {
3421      ndp = ndp2;
3422      goto rep_unops;
3423     }
3424 
3425    if ((ndp2 = parse_term()) == NULL) return(NULL);
3426    /* add to end of possible linear unary operator chain */
3427 unop_ret:
3428    if (lastndp == NULL) unopndp = ndp2; else lastndp->lu.x = ndp2;
3429    return(unopndp);
3430   }
3431  return(parse_term());
3432 }
3433 
3434 /*
3435  * on error in 3 value expression must skip to eox or 1 past same level )
3436  */
skip_3valend(void)3437 static void skip_3valend(void)
3438 {
3439  int32 paren_level;
3440 
3441  for (paren_level = 0; __xndi <= __last_xtk; __xndi++)
3442   {
3443    switch ((byte) __exprtab[__xndi]->optyp) {
3444     case UNDEF: return;
3445     case LPAR: paren_level++; break;
3446     case RPAR:
3447      if (paren_level == 0) { __xndi++; return; }
3448      else paren_level--;
3449    }
3450   }
3451 }
3452 
3453 /*
3454  * return T if expression node is a unary operator that does not require
3455  * special processing
3456  */
is_unop(word32 otyp)3457 static int32 is_unop(word32 otyp)
3458 {
3459  struct opinfo_t *opip;
3460 
3461  opip = &(__opinfo[otyp]);
3462  if (opip->opclass == UNOP || opip->opclass == BOTHOP) return(TRUE);
3463  return(FALSE);
3464 }
3465 
3466 /*
3467  * parse a terminal
3468  *
3469  * expects __xndi at current place and leaves __xndi index one
3470  * past end of terminal
3471  *
3472  * notice Verilog terminals need special routine - too complicated
3473  * to parse using grammar
3474  *
3475  * here can use expridtab and exprtab as arguments to routine because
3476  * these are not overwritten but globals that parsing marches through
3477  *
3478  * no error recovery because already have collected only expr
3479  */
parse_term(void)3480 static struct expr_t *parse_term(void)
3481 {
3482  struct expr_t *ndp, *ndp2, *idndp, *glbndp;
3483  struct sy_t *syp;
3484  struct expridtab_t *xidp;
3485 
3486  /* some kind of terminal */
3487  ndp = __exprtab[__xndi];
3488  switch ((byte) ndp->optyp) {
3489   case NUMBER: case REALNUM: case OPEMPTY:
3490    /* 06/22/00 - SJM - if 2 numeric tokens in a row assume sized num */
3491    /* FIXME - need error recovery here - indicate 2nd is part of 2 tok num */
3492    if (__exprtab[__xndi + 1]->optyp == NUMBER)
3493     {
3494      struct expr_t *ndp3;
3495 
3496      ndp3 = __exprtab[__xndi + 1];
3497      if (!ndp->unsiznum || ndp->ibase != BDEC || ndp3->unsiznum
3498       || ndp3->sizdflt) goto not_2tok_num;
3499      __xndi++;
3500     }
3501 
3502 not_2tok_num:
3503    /* this copies any constant value from __exprtab[] */
3504    ndp = alloc_xtnd(__xndi);
3505    __xndi++;
3506    return(ndp);
3507   case LCB:
3508    ndp2 = parse_concat();
3509    return(ndp2);
3510   case ID:
3511    idndp = alloc_xtnd(__xndi);
3512    xidp = __expr_idtab[__xndi];
3513    /* DBG remove --- */
3514    if (xidp == NULL) __misc_terr(__FILE__, __LINE__);
3515    /* --- */
3516 
3517    /* move one past ID */
3518    __xndi++;
3519    ndp = __exprtab[__xndi];
3520 
3521    /* special case determine and return no argument sys fcall */
3522    /* system function no args legal - $ no ( implies function call */
3523    /* for range expr. ndp sy == NULL true */
3524    /* ID that is system func call, can not be glb. ref. */
3525    /* LOOKATME - can access functions start with $ - think not */
3526    if (xidp->idnam[0] == '$' && ndp->optyp != LPAR)
3527     {
3528      if ((syp = __get_sym(xidp->idnam, __syssyms)) == NULL)
3529       {
3530        __pv_ferr(683,
3531         "call of unknown built-in or unregistered PLI system function %s illegal - for dynamic, register generic place holder",
3532         xidp->idnam);
3533        return(NULL);
3534       }
3535      /* attempt to call ID starting with $ (must be system task?) illegal */
3536      if (syp->sytyp != SYM_SF)
3537       {
3538        __pv_ferr(681,
3539         "illegal call of system task %s - only functions calleable",
3540         syp->synam);
3541        return(NULL);
3542       }
3543 
3544      idndp->lu.sy = syp;
3545      /* error if system function used in xmr */
3546      if (ndp->optyp == DOT)
3547       {
3548        __pv_ferr(1127,
3549         "call of system function %s followed by '.' -  illegal hierarchical reference",
3550         idndp->lu.sy->synam);
3551        return(NULL);
3552       }
3553      ndp2 = __alloc_newxnd();
3554      ndp2->optyp = FCALL;
3555      ndp2->lu.x = idndp;
3556      ndp2->ru.x = NULL;
3557      return(ndp2);
3558     }
3559 
3560 
3561    /* if system func with args, continue to normal fcall */
3562    if (ndp->optyp == LSB)
3563     {
3564      /* inst array ref. then fix global resolution code to make select */
3565      /* on error returns nil - can not parse possible rest of expr */
3566      if ((ndp2 = parse_select(idndp)) == NULL) return(NULL);
3567 
3568      /* xndi one past end of select - xmr is special case */
3569      /* routine will not add path components to current sym table */
3570      if (__exprtab[__xndi]->optyp == DOT)
3571       {
3572        if ((glbndp = parse_glbref(ndp2, xidp)) == NULL) return(NULL);
3573        if (__exprtab[__xndi]->optyp != LPAR) return(glbndp);
3574 
3575        /* xmr followed by ( is function call - 1st comp. inst arr case */
3576        /* can not be system func and therefore '(' required */
3577        ndp2 = parse_fcall(glbndp, NULL, TRUE);
3578        return(ndp2);
3579       }
3580      /* part select never legal for one comp array of insts select */
3581      if (__allow_scope_var && ndp2->optyp == LSB)
3582       {
3583        /* if already declared as net t in current env., know not glb */
3584        /* must also be net - since net is never xmr */
3585        if ((syp = __get_sym_env(xidp->idnam)) != NULL && syp->sytyp == SYM_N)
3586         goto do_decl;
3587 
3588        /* notice this can not fail - make ID into global ref. */
3589        return(bld_1cmp_global(ndp2, xidp));
3590       }
3591 
3592 do_decl:
3593      /* not xmr - declare the ID symbol */
3594      if (!decl_id_inexpr(idndp, xidp)) return(NULL);
3595      return(ndp2);
3596     }
3597    if (ndp->optyp == LPAR)
3598     {
3599 
3600      /* fcall can be xmr, handle in global parsing routine */
3601      /* this works because user function (no $ first char) must have args */
3602      ndp2 = parse_fcall(idndp, xidp, FALSE);
3603      return(ndp2);
3604     }
3605    /* simple ID - current location one after ID */
3606    /* non special terminal - next is lower precedence rest of expr */
3607    if (__exprtab[__xndi]->optyp == DOT)
3608     {
3609      if ((glbndp = parse_glbref(idndp, xidp)) == NULL) return(NULL);
3610 
3611      if (__exprtab[__xndi]->optyp != LPAR) return(glbndp);
3612 
3613      /* xmr followed by ( is function call - non inst array 1st comp case */
3614      ndp2 = parse_fcall(glbndp, NULL, TRUE);
3615      return(ndp2);
3616     }
3617    if (__allow_scope_var)
3618     {
3619      /* notice this can not fail - make ID into global ref. */
3620      return(bld_1cmp_global(idndp, xidp));
3621     }
3622 
3623    if (!decl_id_inexpr(idndp, xidp)) return(NULL);
3624    return(idndp);
3625   case DOT:
3626    /* need exact error for ID that starts with . */
3627    __pv_ferr(1128,
3628     "hierarchical reference or real constant initial '.' illegal");
3629    return(NULL);
3630   default:
3631    if (__pv_err_cnt <= __saverr_cnt)
3632     __pv_ferr(1116, "expression terminal expected - %s read",
3633      to_xndnam(__xs, __xndi));
3634   }
3635  return(NULL);
3636 }
3637 
3638 
3639 /*
3640  * routine to find symbol in symbol table adding if needed
3641  *
3642  * must not call until ID known not to be part of xmr
3643  * name of variable taken from expr id nam global table
3644  */
decl_id_inexpr(struct expr_t * ndp,struct expridtab_t * xidp)3645 static int32 decl_id_inexpr(struct expr_t *ndp, struct expridtab_t *xidp)
3646 {
3647  struct sy_t *syp;
3648  struct net_t *np;
3649 
3650  /* routine never called for function call or task enable */
3651  /* DBG remove --- */
3652  if (xidp->idnam[0] == '$') __arg_terr(__FILE__, __LINE__);
3653  /* --- */
3654 
3655  ndp->lu.x = NULL;
3656  /* since parse range as select with dummy var leave sy field nil for "[]" */
3657  if (xidp->idnam[0] == '[') return(TRUE);
3658 
3659  if ((syp = __get_sym_env(xidp->idnam)) == NULL)
3660   {
3661    /* undeclared specify declared as net var in current sym tab */
3662    if (__cur_declobj == SPECIFY)
3663     syp = __decl_sym(xidp->idnam, __venviron[__top_sti]);
3664    /* undeclared var. declared at module level because task/block */
3665    /* declaration must come first and therefore will be declared */
3666    else
3667     {
3668      if (__iact_state)
3669       {
3670        /* interactive statement - all variables must be declared */
3671        /* for $dumpvars will avoid this code and jump to assume glb */
3672        __pv_err_cnt++;
3673        if (strcmp(xidp->idnam, "") == 0)
3674         {
3675          __ia_err(1436,
3676           "escaped identifier empty - probable white space before escaped continuation new line");
3677         }
3678        else __ia_err(1436, "variable %s not declared", xidp->idnam);
3679        return(FALSE);
3680       }
3681      else syp = __decl_sym(xidp->idnam, __venviron[0]);
3682     }
3683 
3684    np = __add_net(syp);
3685    /* assume register - this is forward decl */
3686    /* even if in specify assume wire and fix up when declared */
3687    np->ntyp = N_REG;
3688    syp->sylin_cnt = xidp->idlin_cnt;
3689    syp->syfnam_ind = xidp->idfnam_ind;
3690   }
3691  ndp->lu.sy = syp;
3692  return(TRUE);
3693 }
3694 
3695 /*
3696  * find a a system task/func symbol (know name starts with $)
3697  * must be system function or task (maybe PLI)
3698  *
3699  * notice no special processing of scale arg. since must be var.
3700  * in module from which scale taken
3701  */
find_systf_sym(struct expridtab_t * xidp)3702 static struct sy_t *find_systf_sym(struct expridtab_t *xidp)
3703 {
3704  struct sy_t *syp;
3705 
3706  /* look up in system task/func symbol table - must be there*/
3707  /* PLI redefine legal and will be in this symbol table */
3708  if ((syp = __get_sym(xidp->idnam, __syssyms)) == NULL)
3709   {
3710    if (__expr_is_lval)
3711     __gferr(1102, xidp->idfnam_ind, xidp->idlin_cnt,
3712      "enable of unknown system task or undefined PLI task %s",
3713      xidp->idnam);
3714    else
3715     __gferr(1102, xidp->idfnam_ind, xidp->idlin_cnt,
3716      "call of unknown system or undefined PLI function %s",
3717      xidp->idnam);
3718    return(NULL);
3719   }
3720  /* if lvalue, must be system table enable */
3721  if (__expr_is_lval)
3722   {
3723    if (syp->sytyp != SYM_STSK)
3724     {
3725      __gferr(1100, xidp->idfnam_ind, xidp->idlin_cnt,
3726       "attempt to enable (not call) system function %s", xidp->idnam);
3727      return(NULL);
3728     }
3729   }
3730  else
3731   {
3732    if (syp->sytyp != SYM_SF)
3733     {
3734      __gferr(1103, xidp->idfnam_ind, xidp->idlin_cnt,
3735       "call of system task %s illegal", xidp->idnam);
3736      return(NULL);
3737     }
3738   }
3739  return(syp);
3740 }
3741 
3742 /*
3743  * parse a concatenate
3744  * know current expr. token is leading { and points to one after }
3745  * on non error (non NULL)  return
3746  *
3747  * form is: {el, el, ..., el}, where el. is <expr.>, { concat, or
3748  * <expr> concat
3749  *
3750  * must be optimized after building tree
3751  * for now optimize just remove one element concatenates and dups
3752  * rep concat. form
3753  */
parse_concat(void)3754 static struct expr_t *parse_concat(void)
3755 {
3756  struct expr_t *ndp, *ndp2, *argndp, *last_ndp;
3757  struct expr_t *lop;
3758 
3759  ndp2 = alloc_xtnd(__xndi);
3760  __xndi++;
3761  ndp2->lu.x = NULL;
3762 
3763  for (last_ndp = NULL;;)
3764   {
3765    if ((argndp = parse_qcexpr()) == NULL) return(NULL);
3766 add_to_tree:
3767    ndp = __exprtab[__xndi];
3768 
3769    /* processing depends on thing after 1st concat el. */
3770    switch ((byte) ndp->optyp) {
3771     case COMMA:
3772      /* build node since at least one more concat element */
3773      lop = __alloc_newxnd();
3774      lop->optyp = CATCOM;
3775      if (last_ndp == NULL) ndp2->ru.x = lop; else last_ndp->ru.x = lop;
3776      lop->lu.x = argndp;
3777      last_ndp = lop;
3778      /* must skip over comma */
3779      __xndi++;
3780      break;
3781     case RCB:
3782      /* done - notice last CATCOM node has NULL right pointer */
3783      lop = __alloc_newxnd();
3784      lop->optyp = CATCOM;
3785      if (last_ndp == NULL) ndp2->ru.x = lop; else last_ndp->ru.x = lop;
3786      lop->lu.x = argndp;
3787      lop->ru.x = NULL;
3788      __xndi++;
3789      return(ndp2);
3790     case LCB:
3791      {
3792       struct expr_t *repndp, *catndp;
3793 
3794       repndp = argndp;
3795       if ((catndp = parse_concat()) == NULL) return(NULL);
3796 
3797       argndp = __alloc_newxnd();
3798       argndp->optyp = CATREP;
3799       argndp->lu.x = repndp;
3800       argndp->ru.x = catndp;
3801      }
3802      goto add_to_tree;
3803     default:
3804      if (__pv_err_cnt <= __saverr_cnt)
3805       __pv_ferr(1119,
3806        "nested concatenate or comma separator expected - %s read",
3807        to_xndnam(__xs, __xndi));
3808      /* as special case for concat, must skip to } if possible */
3809      __vskipto_any(RCB);
3810      return(NULL);
3811     }
3812   }
3813 }
3814 
3815 /*
3816  * parse a select
3817  * copies into malloced storage and return select expr subtree
3818  * know id ndp already copied to malloced storage
3819  *
3820  * [ read - reads one past ending ]
3821  */
parse_select(struct expr_t * idndp)3822 static struct expr_t *parse_select(struct expr_t *idndp)
3823 {
3824  struct expr_t *ndp, *sel_ndp, *i1ndp, *i2ndp;
3825 
3826  /* build (alloc and copy) select sub expression root */
3827  sel_ndp = alloc_xtnd(__xndi);
3828  __xndi++;
3829  /* side effect of parsing sub expression is advancing global x ndi */
3830  /* returned i1ndp is malloced not built in __exprtab */
3831  if ((i1ndp = parse_qcexpr()) == NULL) return(NULL);
3832  sel_ndp->lu.x = idndp;
3833  ndp = __exprtab[__xndi];
3834  if (ndp->optyp == RSB)
3835   {
3836    sel_ndp->ru.x = i1ndp;
3837    __xndi++;
3838    /* next may be dot (handled as term by caller) or rest of expr */
3839    return(sel_ndp);
3840   }
3841  /* part select - if illegal in context caller must detect */
3842  if (ndp->optyp != COLON)
3843   {
3844    if (__pv_err_cnt <= __saverr_cnt)
3845     __pv_ferr(1114,
3846      "bit/part select expression : or ] separator expected - %s read",
3847      to_xndnam(__xs, __xndi));
3848    /* if T, current is one past ending ] */
3849    return(NULL);
3850   }
3851  /* part select after : */
3852  __xndi++;
3853  if ((i2ndp = parse_qcexpr()) == NULL) return(NULL);
3854  ndp = __exprtab[__xndi];
3855  if (ndp->optyp != RSB)
3856   {
3857    if (__pv_err_cnt <= __saverr_cnt)
3858     __pv_ferr(1115,
3859      "part select expression ending ] expected - %s read",
3860      to_xndnam(__xs, __xndi));
3861    return(NULL);
3862   }
3863  sel_ndp->optyp = PARTSEL;
3864  ndp = alloc_xtnd(__xndi);
3865  ndp->optyp = COLON;
3866  sel_ndp->ru.x = ndp;
3867  ndp->lu.x = i1ndp;
3868  ndp->ru.x = i2ndp;
3869  /* move one past RSB if possible */
3870  if (__xndi < __last_xtk) __xndi++;
3871  /* part select never xmr */
3872  return(sel_ndp);
3873 }
3874 
3875 /*
3876  * parse and and build global record for xmr
3877  *
3878  * current expr table node is one past id (dot or [) when called
3879  * reads one past end of xmr
3880  * argument is xmr first component expression and id name tab element
3881  * returns expression that may be select (if var tail is select)
3882  *
3883  * allowing constant selects for arrays of instances and gates
3884  * for say a[a+b].b.c.w[kk], w[kk] is bit select of variable
3885  * for xmr instance allowed context - gets fixed up to instance
3886  *
3887  * changes IDs where unparsed name in expr id tab move to
3888  * expr node with special XMRID node type
3889  */
parse_glbref(struct expr_t * cmp1_ndp,struct expridtab_t * cmp1_xidp)3890 static struct expr_t *parse_glbref(struct expr_t *cmp1_ndp,
3891  struct expridtab_t *cmp1_xidp)
3892 {
3893  int32 is_sel;
3894  struct expr_t *ndp, *glbndp, *last_cmp;
3895  struct expr_t *idndp, *ndp2, *cmp_ndp;
3896  struct expridtab_t *xidp;
3897  struct gref_t *grp;
3898 
3899  /* expr. has top level global then each xmr comma left points to id */
3900  /* or select for inst or gate array */
3901  glbndp = __alloc_newxnd();
3902  glbndp->optyp = GLBREF;
3903  glbndp->ru.x = __alloc_newxnd();
3904  glbndp->ru.x->optyp = XMRCOM;
3905  glbndp->ru.x->lu.x = cmp1_ndp;
3906 
3907  if (cmp1_ndp->optyp == LSB)
3908   {
3909    /* select already parsed and bsel expr. built */
3910    /* cmp ndp ru field set to idnam for first comp. of global */
3911    cmp1_ndp->lu.x->ru.qnchp = __pv_stralloc(cmp1_xidp->idnam);
3912    /* current xndi now one past end of select */
3913    cmp1_ndp->lu.x->optyp = XMRID;
3914   }
3915  else if (cmp1_ndp->optyp == ID)
3916   {
3917    /* unused ru field used for name, lu.sy to xmr dest. filled later */
3918    cmp1_ndp->ru.qnchp = __pv_stralloc(cmp1_xidp->idnam);
3919    cmp1_ndp->optyp = XMRID;
3920   }
3921  else if (cmp1_ndp->optyp != DOT)
3922   {
3923    /* notice here gnam no build and rest of gref expr no read */
3924    __pv_ferr(682, "hierarchical reference contains illegal operator %s",
3925     __to_opname(cmp1_ndp->optyp));
3926    return(NULL);
3927   }
3928 
3929  /* DBG remove --- */
3930  if (__exprtab[__xndi]->optyp != DOT) __arg_terr(__FILE__, __LINE__);
3931  /* --- */
3932 
3933  /* last comp is always right tree end expr. comp */
3934  last_cmp = glbndp->ru.x;
3935  /* know this will be dot at start */
3936  for (;;)
3937   {
3938    /* move one past dot */
3939    __xndi++;
3940    ndp = __exprtab[__xndi];
3941 
3942    /* only use of dot in expr is for xmr - must be followed by ID */
3943    if (ndp->optyp != ID)
3944     {
3945      __pv_ferr(1136,
3946       "hierarchical reference '.' separator not followed by identifier: %s read",
3947       to_xndnam(__xs, __xndi));
3948      return(NULL);
3949     }
3950    idndp = alloc_xtnd(__xndi);
3951    xidp = __expr_idtab[__xndi];
3952    /* DBG remove --- */
3953    if (xidp == NULL) __misc_terr(__FILE__, __LINE__);
3954    /* --- */
3955 
3956    /* move past identifier to dot separator or [ select - any other end */
3957    __xndi++;
3958    ndp = __exprtab[__xndi];
3959    /* assume not a end of xmr select */
3960    is_sel = FALSE;
3961    /* access possible select - if not select add ID */
3962    if (ndp->optyp == LSB)
3963     {
3964      /* cmp ndp copied to malloced storage */
3965      /* in select non xmr expressions added to sym table since */
3966      /* they exist in reference context */
3967      if ((cmp_ndp = parse_select(idndp)) == NULL) return(NULL);
3968      /* current xndi now one past end of select */
3969      cmp_ndp->lu.x->ru.qnchp = __pv_stralloc(xidp->idnam);
3970      cmp_ndp->lu.x->optyp = XMRID;
3971      /* move to next which must be dot after ending ] */
3972      ndp = __exprtab[__xndi];
3973      if (!__allow_scope_var) is_sel = TRUE;
3974      /* inst. part select inside xmrs illegal */
3975      if (cmp_ndp->optyp == PARTSEL && ndp->optyp == DOT)
3976       {
3977        __pv_ferr(682,
3978         "hierarchical reference part select of array of instances illegal");
3979        return(NULL);
3980       }
3981     }
3982    /* know seen ID not followed by . - done */
3983    else
3984     {
3985      /* simple ID component (maybe at end) */
3986      cmp_ndp = idndp;
3987      cmp_ndp->ru.qnchp = __pv_stralloc(xidp->idnam);
3988      cmp_ndp->optyp = XMRID;
3989     }
3990 
3991    if (ndp->optyp != DOT)
3992     {
3993      /* end of xmr - not followed by dot - must be end of expr */
3994      if (!is_sel)
3995       {
3996        /* end is simple ID but must not be added to symbol table */
3997        ndp2 = __alloc_newxnd();
3998        ndp2->optyp = XMRCOM;
3999        ndp2->lu.x = cmp_ndp;
4000        ndp2->ru.x = NULL;
4001        last_cmp->ru.x = ndp2;
4002       }
4003      else
4004       {
4005        /* need to add comp ID to end as ID not select because select of xmr */
4006        ndp2 = __alloc_newxnd();
4007        ndp2->optyp = XMRCOM;
4008        ndp2->lu.x = cmp_ndp->lu.x;
4009        ndp2->ru.x = NULL;
4010        last_cmp->ru.x = ndp2;
4011 
4012        cmp_ndp->lu.x = glbndp;
4013        glbndp = cmp_ndp;
4014       }
4015      break;
4016     }
4017 
4018    /* if followed by '.', add to tail of xmr expr and get next cmp */
4019    ndp2 = __alloc_newxnd();
4020    ndp2->optyp = XMRCOM;
4021    /* know cmp ndp copied to malloced storage */
4022    ndp2->lu.x = cmp_ndp;
4023    ndp2->ru.x = NULL;
4024    last_cmp->ru.x = ndp2;
4025    last_cmp = ndp2;
4026   }
4027  /* tail component is select - assume wire - i.e. not part of inst arr */
4028  /* rare inst. allowd context fixed up later by caller if needed */
4029  /* cmp ndx rotated to become top of select expr. */
4030  /* first add ID part of select to end of xmr */
4031  if (is_sel)
4032   {
4033    grp = __bld_glbref(glbndp->lu.x, cmp1_xidp->idfnam_ind,
4034     cmp1_xidp->idlin_cnt);
4035   }
4036  else
4037   {
4038    /* know x ndi pointing to one past end of xmr */
4039    grp = __bld_glbref(glbndp, cmp1_xidp->idfnam_ind, cmp1_xidp->idlin_cnt);
4040   }
4041 
4042  /* for interactive now can resolve global (case for ID in expr.) */
4043  if (__iact_state)
4044   { __resolve_glbnam(grp); __fill_grp_targu_fld(grp); }
4045  return(glbndp);
4046 }
4047 
4048 /*
4049  * IDs when allow scope var on (scope system task contexts) make globals
4050  *
4051  * during resolution will be converted back to wires if needed
4052  * for these special contexts since need scope ref. even if net with
4053  * same name instance takes precedence (conflict can be labeled block
4054  * local variable versus task name)
4055  */
bld_1cmp_global(struct expr_t * ndp,struct expridtab_t * xidp)4056 static struct expr_t *bld_1cmp_global(struct expr_t *ndp,
4057  struct expridtab_t *xidp)
4058 {
4059  struct expr_t *glbndp, *cmp_ndp;
4060  struct gref_t *grp;
4061 
4062  /* build the one component */
4063  cmp_ndp = ndp;
4064  if (ndp->optyp == ID)
4065   {
4066    cmp_ndp->ru.qnchp = __pv_stralloc(xidp->idnam);
4067    cmp_ndp->optyp = XMRID;
4068   }
4069  else
4070   {
4071    /* build the one component as select form */
4072    cmp_ndp = ndp;
4073    cmp_ndp->lu.x->optyp = XMRID;
4074    cmp_ndp->lu.x->ru.qnchp = __pv_stralloc(xidp->idnam);
4075   }
4076 
4077  /* build the top level global */
4078  glbndp = __alloc_newxnd();
4079  glbndp->optyp = GLBREF;
4080  glbndp->ru.x = __alloc_newxnd();
4081  glbndp->ru.x->optyp = XMRCOM;
4082  glbndp->ru.x->lu.x = cmp_ndp;
4083 
4084  grp = __bld_glbref(glbndp, xidp->idfnam_ind, xidp->idlin_cnt);
4085 
4086  /* for interactive now can resolve global (case for ID in expr.) */
4087  if (__iact_state)
4088   {
4089    /* if really local since dumpvars illegal, caller emits error */
4090    __resolve_glbnam(grp);
4091    if (!grp->gr_gone && !grp->gr_err) __fill_grp_targu_fld(grp);
4092   }
4093  return(glbndp);
4094 }
4095 
4096 /*
4097  * build a global reference entry in work table and convert glb ref ndp
4098  *
4099  * later work table is copied into right size allocated mod table
4100  *
4101  * at this build point, only link if from expression
4102  * caller must set line and file location
4103  */
__bld_glbref(struct expr_t * glbndp,int32 gfnam_ind,int32 glin_cnt)4104 extern struct gref_t *__bld_glbref(struct expr_t *glbndp, int32 gfnam_ind,
4105  int32 glin_cnt)
4106 {
4107  struct gref_t *grp;
4108  struct expr_t *glbpth_ndp;
4109  char *gnam;
4110 
4111  /* convert global expr to name */
4112  /* for inst/gate arrays later will free and regenerate with const indices */
4113  /* notice gnam malloced because xmr expr. can be long here */
4114  /* and malloced to exact size of string (plus room for ending \0) */
4115  gnam = alloc_glbndp_tostr(glbndp);
4116 
4117  if ((++__grwrknum) >= __grwrktabsiz) grow_grtab();
4118  grp = &(__grwrktab[__grwrknum - 1]);
4119 
4120  /* SJM 03/19/00 - gnam malloced above, now linked onto grp - must not free */
4121  init_gref(grp, gnam);
4122  grp->grfnam_ind = gfnam_ind;
4123  grp->grflin_cnt = glin_cnt;
4124 
4125  /* first save global as path expr. then convert to gref */
4126  /* must use glbref because that expr. is linked correctly in source stmts */
4127  glbpth_ndp = glbndp->ru.x;
4128  grp->gxndp = glbndp;
4129  grp->gxndp->ru.grp = grp;
4130 
4131  /* link global reference as XMR expr. off of gref */
4132  grp->glbref = __alloc_newxnd();
4133  grp->glbref->optyp = GLBPTH;
4134  grp->glbref->ru.x = glbpth_ndp;
4135 
4136  /* lu.x gets filled later with destination symbol (of net usually) */
4137  /* DBG remove --- */
4138  if (grp->gxndp->lu.x != NULL) __misc_terr(__FILE__, __LINE__);
4139  /* --- */
4140 
4141  /* accessed through symbol field to gref */
4142  if (__allow_scope_var) grp->gr_inst_ok = TRUE;
4143  if (__iact_state)
4144   {
4145    /* for interact global, current scope determines */
4146    if (__scope_tskp != NULL) grp->grsytp = __scope_tskp->tsksymtab;
4147    else grp->grsytp = __scope_ptr->itip->imsym->el.emdp->msymtab;
4148    grp->gin_mdp = __scope_ptr->itip->imsym->el.emdp;
4149    /* for interactive will be resolved when expression parsed */
4150   }
4151  else
4152   {
4153    /* this is the symbol table gref appears in */
4154    grp->grsytp = __venviron[__top_sti];
4155    grp->gin_mdp = __inst_mod;
4156   }
4157  return(grp);
4158 }
4159 
4160 /*
4161  * grow global gref work table
4162  */
grow_grtab(void)4163 static void grow_grtab(void)
4164 {
4165  int32 old_grtsiz, osize, nsize;
4166 
4167  old_grtsiz = __grwrktabsiz;
4168  osize = old_grtsiz*sizeof(struct gref_t);
4169  __grwrktabsiz = (3*__grwrktabsiz)/2;
4170  nsize = __grwrktabsiz*sizeof(struct gref_t);
4171  __grwrktab = (struct gref_t *) __my_realloc((char *) __grwrktab, osize,
4172   nsize);
4173 }
4174 
4175 /*
4176  * generate a name for a global refence
4177  *
4178  * uses msg expr to string mechanism for instance array selects
4179  * does not assume select is constant expression
4180  *
4181  * LOOKATME - assume xmr component name ID[<expr>] is name and
4182  * therefore expression plus ID must be less the ID max length
4183  */
alloc_glbndp_tostr(struct expr_t * glbndp)4184 static char *alloc_glbndp_tostr(struct expr_t *glbndp)
4185 {
4186  register struct expr_t *gcmp_ndp, *ndp;
4187  int32 slen, glen, gstrsiz;
4188  char *chp, *gnam, s1[IDLEN];
4189 
4190  /* DBG remove --- */
4191  if (glbndp->optyp != GLBREF) __arg_terr(__FILE__, __LINE__);
4192  /* --- */
4193  /* this is starting size only - can grow */
4194  gstrsiz = IDLEN;
4195  gnam = __my_malloc(gstrsiz);
4196  /* must move right down tree one to get first component */
4197  for (gcmp_ndp = glbndp->ru.x, glen = 0;;)
4198   {
4199    ndp = gcmp_ndp->lu.x;
4200    if (ndp->optyp == XMRID) chp = ndp->ru.qnchp;
4201    else if (ndp->optyp == LSB || ndp->optyp == PARTSEL)
4202     {
4203      /* build the <id>[<expr>] expression as string */
4204      /* works because XMRID nodes know to dmp expr */
4205      chp = __msgexpr_tostr(s1, ndp);
4206     }
4207    else { __arg_terr(__FILE__, __LINE__); return(NULL); }
4208 
4209    /* DBG LINT remove -- */
4210    if (chp == NULL) __misc_terr(__FILE__, __LINE__);
4211    /* -- */
4212 
4213    slen = strlen(chp);
4214    /* add room for '.' separator */
4215    if (glen != 0) slen++;
4216    /* need room for one final \0 to end string */
4217    if (glen + slen + 1 >= gstrsiz)
4218     {
4219      gnam = __my_realloc(gnam, gstrsiz, gstrsiz + IDLEN);
4220      gstrsiz += IDLEN;
4221     }
4222    if (glen == 0) strcpy(gnam, chp);
4223    else { gnam[glen] = '.'; strcpy(&(gnam[glen + 1]), chp); }
4224    glen += slen;
4225 
4226    if ((gcmp_ndp = gcmp_ndp->ru.x) == NULL) break;
4227    /* DBG remove --- */
4228    if (gcmp_ndp->optyp != XMRCOM) __arg_terr(__FILE__, __LINE__);
4229    /* --- */
4230   }
4231  gnam[glen] = '\0';
4232  /* realloc to exact string size */
4233  if (glen + 1 != gstrsiz)
4234   {
4235    gnam = __my_realloc(gnam, gstrsiz, glen + 1);
4236   }
4237  return(gnam);
4238 }
4239 
4240 /*
4241  * convert glb ref expression into string
4242  *
4243  * when first read now since do not know index constant expression values
4244  * is printed name - fixed later to use number indices
4245  */
4246 
4247 /*
4248  * allocate a input phase global ref. record
4249  *
4250  * BEWARE - gnam must be malloced not fixed string
4251  */
init_gref(struct gref_t * grp,char * gnam)4252 static void init_gref(struct gref_t *grp, char *gnam)
4253 {
4254  grp->gnam = gnam;
4255  grp->gr_err = FALSE;
4256  /* assume in decl. code */
4257  grp->upwards_rel = FALSE;
4258  grp->is_upreltsk = FALSE;
4259  grp->is_rooted = FALSE;
4260  grp->path_has_isel = FALSE;
4261  grp->pathisel_done = FALSE;
4262  grp->gr_inst_ok = FALSE;
4263  grp->gr_defparam = FALSE;
4264  grp->gr_gone = FALSE;
4265 
4266  grp->gxndp = NULL;
4267  grp->glbref = NULL;
4268  grp->grsytp = NULL;
4269  grp->targmdp = NULL;
4270  grp->targtskp = NULL;
4271  grp->grfnam_ind = 0;
4272  grp->grflin_cnt = 0;
4273  grp->grcmps = NULL;
4274  grp->grxcmps = NULL;
4275  grp->last_gri = -1;
4276  grp->targu.targitp = NULL;
4277  grp->targsyp = NULL;
4278  grp->spltgrp = NULL;
4279 }
4280 
4281 /*
4282  * parse a function call
4283  * called when ( seen immediately after
4284  * know __xndi points to ( and moves one past ending )
4285  * ,, form legal for system functions but not user - caught elsewhere
4286  */
parse_fcall(struct expr_t * fcall_ndp,struct expridtab_t * xidp,int32 is_glb)4287 static struct expr_t *parse_fcall(struct expr_t *fcall_ndp,
4288  struct expridtab_t *xidp, int32 is_glb)
4289 {
4290  int32 is_sysfunc;
4291  struct expr_t *ndp, *fchdrx, *argndp, *last_ndp, *lop;
4292 
4293  is_sysfunc = FALSE;
4294  /* for non global function call, check symbol type and add if needed */
4295  if (!is_glb)
4296   {
4297    /* only fails if interactive and unable to find - stmt parser handles */
4298    /* error skipping */
4299    if (!chk_decl_func(&is_sysfunc, fcall_ndp, xidp)) return(NULL);
4300   }
4301  else
4302   {
4303    /* because can not tell if select of last component is from wire */
4304    /* error if global is select - no other checking possible here */
4305    if (fcall_ndp->optyp != GLBREF)
4306     {
4307      __pv_ferr(1137,
4308       "hierarchical function call name %s illegal select",
4309       __msgexpr_tostr(__xs, fcall_ndp));
4310      return(NULL);
4311     }
4312   }
4313 
4314  fchdrx = alloc_xtnd(__xndi);
4315  fchdrx->optyp = FCALL;
4316  fchdrx->lu.x = fcall_ndp;
4317  __xndi++;
4318  ndp = __exprtab[__xndi];
4319  if (ndp->optyp == RPAR && !is_sysfunc)
4320   {
4321    __pv_ferr(1120,
4322    "Verilog user defined function call requires at least one argument - () illegal");
4323    return(NULL);
4324   }
4325  /* now checking moved 1 past 1st token of 1st expr. */
4326  /* expr. structure identical to concatenate , present even for 1 arg. */
4327  /* can trace through br x rights until NULL */
4328  /* task port list for functs has extra 1st ret. argument but not expr. */
4329  for (last_ndp = fchdrx;;)
4330   {
4331    ndp = __exprtab[__xndi];
4332    /* case 1: empty expr. only allowed for built-in or PLI sysfuncs */
4333    if (ndp->optyp == COMMA || ndp->optyp == RPAR)
4334     {
4335      if (!is_sysfunc)
4336       {
4337        __pv_ferr(1121,
4338         "user function %s call empty ',,' argument form illegal",
4339         __to_idnam(fcall_ndp));
4340        argndp = __alloc_newxnd();
4341        /* user function error, make 1 bit x */
4342        __set_numval(argndp, 1L, 1L, 1);
4343       }
4344      else
4345       {
4346        /* must allocate new xnode because need both ,'s of ,, */
4347        argndp = __alloc_newxnd();
4348        argndp->optyp = OPEMPTY;
4349        argndp->folded = TRUE;
4350       }
4351     }
4352    else
4353     {
4354      /* case 2: actual expr */
4355      /* case 2a: PLI system function - xmr arguments legal for any arg */
4356      if (is_sysfunc)
4357       {
4358        struct sy_t *syp;
4359        struct sysfunc_t *sfbp;
4360 
4361        syp = fcall_ndp->lu.sy;
4362        sfbp = syp->el.esyftbp;
4363 
4364        /* XMR's (scope args) legal for built-in system functions */
4365        /* but can never be function scope since functions always called */
4366        if (sfbp->syfnum >= BASE_VERIUSERTFS)
4367         {
4368          if (sfbp->syfnum > __last_systf) __misc_terr(__FILE__, __LINE__);
4369 
4370          /* PLI user defined system function - must allow */
4371          __allow_scope_var = TRUE;
4372         }
4373        /* turning on allow scope global - turns on conversion in here */
4374        if ((argndp = parse_qcexpr()) == NULL)
4375         {
4376          __allow_scope_var = FALSE;
4377          return(NULL);
4378         }
4379        /* must turn off allowing scope for both paths thru ifs */
4380        __allow_scope_var = FALSE;
4381       }
4382      else
4383       {
4384        /* case 2b: use defined (non sysf or PLI sysf)  function */
4385        /* SJM 07/26/99 - was return FALSE but same NULL */
4386        if ((argndp = parse_qcexpr()) == NULL) return(NULL);
4387 
4388         /* DBG remove ---
4389         if (__debug_flg)
4390          __dbg_msg("ARG FCALL: %s\n", __msgexpr_tostr(__xs, argndp));
4391         --- */
4392       }
4393     }
4394 
4395    ndp = __exprtab[__xndi];
4396    if (ndp->optyp != RPAR && ndp->optyp != COMMA)
4397     {
4398      if (__pv_err_cnt <= __saverr_cnt)
4399       __pv_ferr(1122,
4400        "function call argument , or ) separator expected - %s read",
4401        __to_opname(ndp->optyp));
4402      return(NULL);
4403     }
4404    lop = __alloc_newxnd();
4405    lop->optyp = FCCOM;
4406    lop->ru.x = NULL;
4407    lop->lu.x = argndp;
4408    last_ndp->ru.x = lop;
4409    last_ndp = lop;
4410    __xndi++;
4411    if (ndp->optyp == RPAR) break;
4412   }
4413  /* DBG remove ---
4414  if (__debug_flg)
4415   __dbg_msg("FCALL: %s\n", __msgexpr_tostr(__xs, fchdrx));
4416  --- */
4417  return(fchdrx);
4418 }
4419 
4420 /*
4421  * check and declare a non xmr function call expression
4422  *
4423  * know ID and following '(' read - must find or maybe add func symbol
4424  * xidp ok here since only declaring no movement in symbol table
4425  */
chk_decl_func(int32 * is_sysfunc,struct expr_t * idndp,struct expridtab_t * xidp)4426 static int32 chk_decl_func(int32 *is_sysfunc, struct expr_t *idndp,
4427  struct expridtab_t *xidp)
4428 {
4429  struct sy_t *syp;
4430  char s1[RECLEN];
4431 
4432  *is_sysfunc = FALSE;
4433  /* if starts with '$' must be system function */
4434  if (xidp->idnam[0] == '$')
4435   {
4436    if ((syp = find_systf_sym(xidp)) == NULL) return(FALSE);
4437    idndp->lu.sy = syp;
4438    *is_sysfunc = TRUE;
4439    return(TRUE);
4440   }
4441  /* SJM 02/01/05 - change to use tf undef work symtab - for uprel 1 cmp glb */
4442  /* look up to see if previously declared as function or used as func */
4443  if ((syp = __get_sym(xidp->idnam, __venviron[0])) == NULL)
4444   {
4445    /* for interactive must already be declared or error */
4446    if (__iact_state)
4447     {
4448      /* interactive statement - all variables must be declared */
4449      /* for $dumpvars will avoid this code and jump to assume glb */
4450      __pv_err_cnt++;
4451      __ia_err(1436, "function %s not declared", xidp->idnam);
4452      return(FALSE);
4453     }
4454    /* SJM 02/01/05 - must assume 1 comp XMR - if declared later will be */
4455    /* changed back in resolv local path routine */
4456    cnvt_forw_tfcall_1cmpglb(idndp, xidp->idnam, xidp->idfnam_ind,
4457     xidp->idlin_cnt);
4458    return(TRUE);
4459   }
4460  /* if already in symbol table as wire error - used as wire */
4461  idndp->lu.sy = syp;
4462 
4463  /* if declared (or just seen) but not as fcall error */
4464  if (syp->sytyp != SYM_F)
4465   {
4466    if (syp->sydecl)
4467     {
4468      __pv_ferr(1123,
4469       "%s called as function but symbol declared with type %s",
4470       __to_idnam(idndp), __to_sytyp(s1, syp->sytyp));
4471     }
4472    else
4473     {
4474      __pv_ferr(1123,
4475       "%s called as function but symbol previously used with type %s",
4476       __to_idnam(idndp), __to_sytyp(s1, syp->sytyp));
4477     }
4478    /* return T since can continue parsing with wrong type symbol */
4479   }
4480  return(TRUE);
4481 }
4482 
4483 /*
4484  * routine to build func call 1 comp global for forward refs
4485  *
4486  * special case because must convert top node to xmr and make left
4487  * offspring newly allocated with same contents
4488  *
4489  * needed because f([args]) may be upward relative xmr to f in above
4490  * module - can't tell so any function call use before declares must
4491  * be assumed to be XMRs - will get changed back if decl later in mod
4492  */
cnvt_forw_tfcall_1cmpglb(struct expr_t * ndp,char * tfnam,int32 fnam_ind,int32 lin_cnt)4493 static void cnvt_forw_tfcall_1cmpglb(struct expr_t *ndp, char *tfnam,
4494  int32 fnam_ind, int32 lin_cnt)
4495 {
4496  struct expr_t *cmp_ndp, sav_xnod;
4497  struct gref_t *grp;
4498 
4499  /* DBG remove -- */
4500  if (ndp->optyp != ID) __misc_terr(__FILE__, __LINE__);
4501  /* -- */
4502 
4503  sav_xnod = *ndp;
4504  ndp->optyp = GLBREF;
4505  ndp->ru.x = __alloc_newxnd();
4506  ndp->ru.x->optyp = XMRCOM;
4507  cmp_ndp = __alloc_newxnd();
4508  *cmp_ndp = sav_xnod;
4509  ndp->ru.x->lu.x = cmp_ndp;
4510  ndp->ru.x->ru.x = NULL;
4511 
4512  cmp_ndp->ru.qnchp = __pv_stralloc(tfnam);
4513  cmp_ndp->optyp = XMRID;
4514 
4515  grp = __bld_glbref(ndp, fnam_ind, lin_cnt);
4516 }
4517 
4518 /*
4519  * convert event expression table to expression tree
4520  */
__bld_evxtree(void)4521 extern void __bld_evxtree(void)
4522 {
4523  struct expr_t *ndp;
4524 
4525  /* add end of expression fence */
4526  ndp = __alloc_exprnd();
4527  ndp->optyp = UNDEF;
4528  __xndi = 0;
4529  if ((__root_ndp = parse_evexpr()) == NULL || __xndi != __last_xtk)
4530   {
4531    if (__pv_err_cnt <= __saverr_cnt)
4532     __pv_ferr(1124, "event expression error at token [%s]",
4533      to_xndnam(__xs, __xndi));
4534    __root_ndp = __alloc_newxnd();
4535    __set_numval(__root_ndp, 1L, 1L, 1);
4536   }
4537  /* if (__debug_flg) __dbg_msg(__msgexpr_tostr(__xs, __root_ndp)); */
4538 }
4539 
4540 /*
4541  * parse a specialized event expression
4542  */
parse_evexpr(void)4543 static struct expr_t *parse_evexpr(void)
4544 {
4545  struct expr_t *ndp, *ndp2, *ndp3, *ndp4, *rhsndp, *leftopndp;
4546 
4547  /* SJM 08/22/00 - need to separate of possible leading pos/neg edge */
4548  /* because they apply to entire rest of expr to end or ev or */
4549  ndp = __exprtab[__xndi];
4550  if (ndp->optyp == OPPOSEDGE || ndp->optyp == OPNEGEDGE)
4551   {
4552    ndp3 = alloc_xtnd(__xndi);
4553    __xndi++;
4554   }
4555  else ndp3 = NULL;
4556 
4557  /* routine leaves __xndi at next place to look */
4558  if ((leftopndp = parse_qcexpr()) == NULL) return(NULL);
4559  if (ndp3 != NULL) { ndp3->lu.x = leftopndp; leftopndp = ndp3; }
4560 
4561  ndp = __exprtab[__xndi];
4562  for (;;)
4563   {
4564    if (ndp->optyp == OPEVOR || ndp->optyp == OPEVCOMMAOR)
4565     {
4566      ndp2 = alloc_xtnd(__xndi);
4567      __xndi++;
4568 
4569      /* SJM 08/22/00 - need to separate of possible leading pos/neg edge */
4570      /* because they apply to entire rest of expr to end or ev or */
4571      ndp4 = __exprtab[__xndi];
4572      if (ndp4->optyp == OPPOSEDGE || ndp4->optyp == OPNEGEDGE)
4573       {
4574        ndp3 = alloc_xtnd(__xndi);
4575       __xndi++;
4576       }
4577      else ndp3 = NULL;
4578 
4579      if ((rhsndp = parse_qcexpr()) == NULL) break;
4580      if (ndp3 != NULL) { ndp3->lu.x = rhsndp; rhsndp = ndp3; }
4581 
4582      /* this makes sure optyp right */
4583      ndp2->lu.x = leftopndp;
4584      ndp2->ru.x = rhsndp;
4585      leftopndp = ndp2;
4586      ndp = __exprtab[__xndi];
4587     }
4588    else break;
4589   }
4590  return(leftopndp);
4591 }
4592 
4593 /*
4594  * LOW LEVEL EXPRESSION NODE ROUTINES
4595  */
4596 
4597 /*
4598  * convert a symbol into a expression
4599  *
4600  * easy because all the normal work of parse term for ID is
4601  * declaring symbol
4602  */
__gen_wireid_expr(struct sy_t * syp)4603 extern struct expr_t *__gen_wireid_expr(struct sy_t *syp)
4604 {
4605  struct expr_t *ndp;
4606 
4607  ndp = __alloc_newxnd();
4608  ndp->lu.sy = syp;
4609  ndp->optyp = ID;
4610  return(ndp);
4611 }
4612 
4613 /*
4614  * allocate an expression node in fixed current expr. array
4615  *
4616  * this sets node type to be operator
4617  * if used as number must have a/b val allocated
4618  * when allocated for expr. allocated a/b values used
4619  */
__alloc_exprnd(void)4620 extern struct expr_t *__alloc_exprnd(void)
4621 {
4622  struct expr_t *ndp;
4623 
4624  /* SJM 11/22/01 - can't use fixed operator precedence xpr tab */
4625  /* need malloced for very large bus concatenates */
4626  if (++__last_xtk >= __exprtabsiz - 1) grow_exprtab();
4627  if ((ndp = __exprtab[__last_xtk]) == NULL)
4628   {
4629    ndp = my_xndalloc();
4630    __exprtab[__last_xtk] = ndp;
4631   }
4632  __init_xnd(ndp);
4633  return(ndp);
4634 }
4635 
4636 /*
4637  *
4638  * grow exprtab used during operator precedence expr tab * parsing
4639  *
4640  * can realloc because contains ptr's to malloced expr nodes where
4641  * node but not table is linked together to form run time expr
4642  *
4643  * but notice expr id table must increased to same size to avoid
4644  * overflow check
4645  *
4646  * SJM 10/22/01
4647  */
grow_exprtab(void)4648 static void grow_exprtab(void)
4649 {
4650  register int32 i;
4651  int32 old_xtabsiz, osize, nsize;
4652 
4653  old_xtabsiz = __exprtabsiz;
4654  osize = old_xtabsiz*sizeof(struct expr_t *);
4655  __exprtabsiz = (3*__exprtabsiz)/2;
4656  nsize = __exprtabsiz*sizeof(struct expr_t *);
4657  __exprtab = (struct expr_t **) __my_realloc((char *) __exprtab,
4658   osize, nsize);
4659  for (i = old_xtabsiz - 1; i < __exprtabsiz; i++) __exprtab[i] = NULL;
4660 
4661  /* also must grow expr id table */
4662  osize = old_xtabsiz*sizeof(struct expridtab_t *);
4663  nsize = __exprtabsiz*sizeof(struct expridtab_t *);
4664  __expr_idtab = (struct expridtab_t **)
4665   __my_realloc((char *) __expr_idtab, osize, nsize);
4666  for (i = old_xtabsiz - 1; i < __exprtabsiz; i++) __expr_idtab[i] = NULL;
4667 }
4668 
4669 /*
4670  * allocate a expr ID table entry
4671  */
__alloc_expridnd(char * idnam)4672 extern struct expridtab_t *__alloc_expridnd(char *idnam)
4673 {
4674  int32 slen;
4675  struct expridtab_t *xidp;
4676 
4677  if ((xidp = __expr_idtab[__last_xtk]) == NULL)
4678   {
4679    xidp = (struct expridtab_t *) __my_malloc(sizeof(struct expridtab_t));
4680    __expr_idtab[__last_xtk] = xidp;
4681    xidp->idnam = NULL;
4682    xidp->idfldwid = 0;
4683   }
4684  slen = strlen(idnam);
4685  if (slen + 1 > xidp->idfldwid)
4686   {
4687    /* guess 2x so prevent increase by one byte allocs */
4688    xidp->idnam = __my_malloc(2*slen + 1);
4689    xidp->idfldwid = 2*slen + 1;
4690   }
4691  strcpy(xidp->idnam, idnam);
4692  xidp->idlin_cnt = __lin_cnt;
4693  xidp->idfnam_ind = __cur_fnam_ind;
4694  return(xidp);
4695 }
4696 
4697 /*
4698  * allocate an expr node
4699  */
my_xndalloc(void)4700 static struct expr_t *my_xndalloc(void)
4701 {
4702  struct expr_t *ndp;
4703 
4704  ndp = (struct expr_t *) __my_malloc(sizeof(struct expr_t));
4705  ndp->optyp = UNDEF;
4706  if (__inst_mod != NULL) (__inst_mod->mexprnum)++;
4707  return(ndp);
4708 }
4709 
4710 /*
4711  * allocate a copy of __exprtab node in malloced storage
4712  * this uses the allocated values in the __exprtab node
4713  *
4714  * numeric values never changed because __exprtab node just points to
4715  * atokptr and btokptr and those values moved to malloced node
4716  */
alloc_xtnd(int32 ndi)4717 static struct expr_t *alloc_xtnd(int32 ndi)
4718 {
4719  struct expr_t *ndp, *ndp2;
4720 
4721  /* xtnd out of range */
4722  if (ndi < 0 || ndi > __last_xtk) __misc_terr(__FILE__, __LINE__);
4723  ndp = my_xndalloc();
4724  ndp2 = __exprtab[ndi];
4725  *ndp = *ndp2;
4726  return(ndp);
4727 }
4728 
4729 /*
4730  * initialize a new node - assume expression node for now
4731  */
__init_xnd(struct expr_t * ndp)4732 extern void __init_xnd(struct expr_t *ndp)
4733 {
4734  ndp->optyp = UNDEF;
4735  ndp->has_sign = FALSE;
4736  ndp->rel_ndssign = FALSE;
4737  ndp->is_string = FALSE;
4738  /* unless simple decimal, must be sized */
4739  ndp->unsiznum = FALSE;
4740  ndp->ibase = BHEX;
4741  ndp->sizdflt = FALSE;
4742  ndp->is_real = FALSE;
4743  ndp->cnvt_to_real = FALSE;
4744  ndp->unsgn_widen = FALSE;
4745  ndp->consubxpr = FALSE;
4746  ndp->consub_is = FALSE;
4747  ndp->folded = FALSE;
4748  ndp->getpatlhs = FALSE;
4749  ndp->ind_noth0 = FALSE;   /* assume h:0 form */
4750  ndp->x_multfi = FALSE;
4751  ndp->tf_isrw = FALSE;
4752  ndp->x_islhs = FALSE;
4753  ndp->locqualnam = FALSE;
4754  ndp->lhsx_ndel = FALSE;
4755  ndp->x_stren = FALSE;
4756  ndp->unc_pull = NO_UNCPULL;
4757  ndp->szu.xclen = 0;
4758  ndp->lu.x = ndp->ru.x = NULL;
4759 }
4760 
4761 /*
4762  * allocate and initialize new expression node (may be table)
4763  * this initializes a node so if copied to number will have value alloced
4764  */
__alloc_newxnd(void)4765 extern struct expr_t *__alloc_newxnd(void)
4766 {
4767  struct expr_t *ndp;
4768 
4769  ndp = my_xndalloc();
4770  __init_xnd(ndp);
4771  return(ndp);
4772 }
4773 
4774 /*
4775  * run time (during sim or xform) allocate new xnode
4776  * does not get copied to mod's expr table
4777  */
__sim_alloc_newxnd(void)4778 extern struct expr_t *__sim_alloc_newxnd(void)
4779 {
4780  struct expr_t *ndp;
4781 
4782  ndp = (struct expr_t *) __my_malloc(sizeof(struct expr_t));
4783  ndp->optyp = UNDEF;
4784  __init_xnd(ndp);
4785  return(ndp);
4786 }
4787 
4788 /*
4789  * set an collection routine exprtab entry to x
4790  * this must be called for empty expr. tab - all fields reclaimed
4791  */
__set_xtab_errval(void)4792 extern void __set_xtab_errval(void)
4793 {
4794  __last_xtk = 0;
4795  __init_xnd(__exprtab[0]);
4796  __set_numval(__exprtab[0], 1L, 1L, 1);
4797 }
4798 
4799 /*
4800  * set an collection routine exprtab entry to 0 - for specify
4801  * this must be called for empty expr. tab - all fields reclaimed
4802  */
__set_0tab_errval(void)4803 extern void __set_0tab_errval(void)
4804 {
4805  __last_xtk = 0;
4806  __set_numval(__exprtab[0], 0L, 0L, 1);
4807 }
4808 
4809 /*
4810  * free an expression tree
4811  * notice cannot free symbols or wires pointed to by these nodes
4812  * ndp now points to garbage - caller must unlink
4813  */
__free_xtree(struct expr_t * ndp)4814 extern void __free_xtree(struct expr_t *ndp)
4815 {
4816  if (ndp == NULL) return;
4817  /* first free underneath */
4818  __free2_xtree(ndp);
4819  /* then node itself */
4820  __my_free((char *) ndp, sizeof(struct expr_t));
4821 }
4822 
4823 /*
4824  * free all nodes under expression node and free number if needed
4825  * notice cannot free symbols or wires pointed to by these nodes
4826  * expects __inst_mod to be set if form is IS
4827  * caller to reuse ndp must change fields
4828  *
4829  * notice freeing here assumes that all nodes have both a and b parts
4830  */
__free2_xtree(struct expr_t * ndp)4831 extern void __free2_xtree(struct expr_t *ndp)
4832 {
4833  switch ((byte) ndp->optyp) {
4834   case NUMBER: case REALNUM: case OPEMPTY:
4835    ndp->ru.xvi = -1;
4836    return;
4837   case ISNUMBER: case ISREALNUM:
4838    /* LOOKATME - unable to free IS constant value parts - is this leak? */
4839    ndp->ru.xvi = -1;
4840    return;
4841   case ID:
4842    ndp->lu.sy = NULL;
4843    return;
4844   case GLBREF:
4845    ndp->lu.sy = NULL;
4846    /* globals free elsewhere - through glogal list */
4847    ndp->ru.grp = NULL;
4848    return;
4849   case XMRID:
4850    __my_free(ndp->ru.qnchp, strlen(ndp->ru.qnchp) + 1);
4851    /* DBG remove --- */
4852    ndp->ru.x = NULL;
4853    /* --- */
4854    return;
4855   /* fall thru for GLBPTH that has no contents - just subexprs under */
4856  }
4857  if (ndp->lu.x != NULL) __free_xtree(ndp->lu.x);
4858  if (ndp->ru.x != NULL) __free_xtree(ndp->ru.x);
4859 }
4860 
4861 /*
4862  * build an unc. expression - may have width set to 1 for now - know later
4863  * before calling must free exprtab and anything pointed to __root_ndp
4864  */
__bld_unc_expr(void)4865 extern void __bld_unc_expr(void)
4866 {
4867  __root_ndp = __alloc_newxnd();
4868  set2_opempty(__root_ndp);
4869 }
4870 
4871 /*
4872  * this build a 1 token empty expr that may or may not be parsed
4873  * this is for 1 bit expression
4874  *
4875  * this does not free partially built x trees - caller must free if needed
4876  */
__set_opempty(int32 ndi)4877 extern void __set_opempty(int32 ndi)
4878 {
4879  __init_xnd(__exprtab[ndi]);
4880  set2_opempty(__exprtab[ndi]);
4881 }
4882 
4883 /*
4884  * version of set opempty that is passed allocated expr. value
4885  */
set2_opempty(struct expr_t * ndp)4886 static void set2_opempty(struct expr_t *ndp)
4887 {
4888  ndp->optyp = OPEMPTY;
4889  ndp->folded = TRUE;
4890  ndp->szu.xclen = 1;
4891  /* if unconnected drive active, must set in node */
4892  if (__unconn_drive != TOK_NONE)
4893   {
4894    ndp->unc_pull = (__unconn_drive == PULL0) ? UNCPULL0 : UNCPULL1;
4895    ndp->x_stren = TRUE;
4896    /* must force propogating strengths up and down */
4897    /* but maybe no wire marked as strength */
4898    __design_no_strens = FALSE;
4899   }
4900 }
4901 
4902 /*
4903  * set an already allocated leaf node (no subnodes) to a numeric value
4904  * only for <= WBITS values and node must be new - know previous alloc num
4905  *
4906  * notice this must not change __root_ndp
4907  */
__set_numval(struct expr_t * ndp,word32 av,word32 bv,int32 blen)4908 extern void __set_numval(struct expr_t *ndp, word32 av, word32 bv, int32 blen)
4909 {
4910  ndp->optyp = NUMBER;
4911  if (blen <= WBITS)
4912   {
4913    ndp->ru.xvi = __alloc_shareable_cval(av, bv, blen);
4914   }
4915  else __case_terr(__FILE__, __LINE__);
4916  ndp->szu.xclen = blen;
4917  if (bv == 0) ndp->ibase = BDEC;
4918 }
4919 
4920 /*
4921  * print an expression node for error messages
4922  * must be wide enough for id
4923  * this is a routine that uses wr to exprline routines so cannot be
4924  * called to add to exprline - must use disp of expr. routine
4925  *
4926  * BEWARE - can only be called during expression reading because needs
4927  *          __exprtab and __expridtab
4928  */
to_xndnam(char * s,int32 xndi)4929 static char *to_xndnam(char *s, int32 xndi)
4930 {
4931  int32 wlen;
4932  word32 *ap, *bp;
4933  struct expr_t *ndp;
4934  struct expridtab_t *xidp;
4935  char s1[2*IDLEN], s2[RECLEN];
4936 
4937  ndp = __exprtab[xndi];
4938  switch ((byte) ndp->optyp) {
4939   case ID:
4940    xidp = __expr_idtab[xndi];
4941    if (xidp == NULL || strcmp(xidp->idnam, "") == 0)
4942     { strcpy(s, "**range**"); return(s); }
4943    sprintf(s1, "IDENTIFIER: %s", xidp->idnam);
4944    break;
4945    /* LOOKATME - can GLBREF occur here */
4946   case NUMBER:
4947   case ISNUMBER:
4948    ap = &(__contab[ndp->ru.xvi]);
4949    wlen = wlen_(ndp->szu.xclen);
4950    bp = &ap[wlen];
4951    sprintf(s1, "NUMBER: %s", __regab_tostr(s2, ap, bp, ndp->szu.xclen,
4952     BHEX, FALSE));
4953    break;
4954   case REALNUM: case ISREALNUM:
4955    /* LOOKATME - better to just format as double */
4956    /* just pass a part for both here */
4957    ap = &(__contab[ndp->ru.xvi]);
4958    sprintf(s1, "REAL: %s", __regab_tostr(s2, ap, ap, ndp->szu.xclen, BDBLE,
4959     FALSE));
4960    break;
4961   case OPEMPTY:
4962    strcpy(s, "<EMPTY>");
4963    return(s);
4964   case UNDEF:
4965    strcpy(s, "<EXPR END>");
4966    return(s);
4967   default:
4968    strcpy(s, __to_opname(ndp->optyp)); return(s);
4969  }
4970  if ((int32) strlen(s1) >= RECLEN - 1) s1[RECLEN - 1] = '\0';
4971  strcpy(s, s1);
4972  return(s);
4973 }
4974