1 /****************************************************************************
2     Copyright (C) 1987-2015 by Jeffery P. Hansen
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 
18     Last edit by hansen on Mon Feb  2 16:54:46 2009
19 ****************************************************************************/
20 #include "thyme.h"
21 
22 static char lastExprError[STRMAX] = "";
23 
24 /*****************************************************************************
25  * Precedence level at which to omit spaces arround the operator when
26  * printing.
27  *****************************************************************************/
28 #define TIGHT_LEVEL 11
29 
30 /*
31  * Operator table
32  */
33 extern OpDesc opTable[];
34 extern int opTable_size;
35 
36 /*****************************************************************************
37  *
38  * Get the last error message resulting from an expression manipulation.
39  *
40  * Parameters:
41  *     buf		Buffer in which to store message.
42  *
43  *****************************************************************************/
Expr_getLastError(char * buf)44 void Expr_getLastError(char *buf)
45 {
46   strcpy(buf, lastExprError);
47 }
48 
49 /*****************************************************************************
50  *
51  * Find the operator descriptor for the specified expression code
52  *
53  * Parameters:
54  *     code		Code to look up
55  *
56  * Returns:		Operator descritor if found, null if not found.
57  *
58  *****************************************************************************/
OpDesc_find(exprcode_t code)59 static OpDesc *OpDesc_find(exprcode_t code)
60 {
61   int i;
62 
63   for (i = 0;i < opTable_size;i++) {
64     if (opTable[i].od_type == code)
65       return &opTable[i];
66   }
67   return 0;
68 }
69 
70 /*****************************************************************************
71  *
72  * Find the operator descriptor from a function pointer
73  *
74  * Parameters:
75  *     func		Code to look up
76  *
77  * Returns:		Operator descritor if found, null if not found.
78  *
79  *****************************************************************************/
OpDesc_findFunc(valueop_f * opfunc)80 OpDesc *OpDesc_findFunc(valueop_f *opfunc)
81 {
82   int i;
83 
84   for (i = 0;i < opTable_size;i++) {
85     if (opTable[i].od_opfunc == opfunc || opTable[i].od_w_opfunc == opfunc)
86       return &opTable[i];
87   }
88   return 0;
89 }
90 
91 /*****************************************************************************
92  *
93  * Create a literal expression
94  *
95  * Parameters:
96  *     name		String with literal name.
97  *
98  * Returns:		Expression object representing an identifier.
99  *
100  *****************************************************************************/
new_Expr_lit(const char * name)101 Expr *new_Expr_lit(const char *name)
102 {
103   Expr *e = (Expr*) malloc(sizeof(Expr));
104 
105   e->e_type = E_LITERAL;
106   e->e.literal.name = strdup(name);
107   if (strchr(name,'.'))
108     e->e.literal.ishlit = 1;
109   else
110     e->e.literal.ishlit = 0;
111 
112   return e;
113 }
114 
115 /*****************************************************************************
116  *
117  * Create a task expression
118  *
119  * Parameters:
120  *     name		Name of task to execute
121  *     args		Arguments of task
122  *
123  * Returns:		Expression object representing a task.
124  *
125  *****************************************************************************/
new_Expr_task(const char * name,List * args)126 Expr *new_Expr_task(const char *name,List *args)
127 {
128   Expr *e = (Expr*) malloc(sizeof(Expr));
129 
130   e->e_type = E_TASK;
131   e->e.task.name = strdup(name);
132   e->e.task.argc = args ? List_numElems(args) : 0;
133   e->e.task.argv = 0;
134 
135   if (args && List_numElems(args) > 0) {
136     ListElem *le;
137     int i = 0;
138 
139     e->e.task.argv = (Expr**) malloc(List_numElems(args)*sizeof(Expr*));
140     for (le = List_first(args);le;le = List_next(args,le)) {
141       e->e.task.argv[i++] = (Expr*) ListElem_obj(le);
142     }
143   }
144 
145   return e;
146 }
147 
148 
149 /*****************************************************************************
150  *
151  * Create a single operand operator expression
152  *
153  * Parameters:
154  *     op		Operator code
155  *     x		Expression being operated on.
156  *
157  * Returns:		Single operand operator expression.
158  *
159  *****************************************************************************/
new_Expr_op1(exprcode_t op,Expr * x)160 Expr *new_Expr_op1(exprcode_t op,Expr *x)
161 {
162   Expr *e = (Expr*) malloc(sizeof(Expr));
163 
164   e->e_type = op;
165   e->e.opr[0] = 0;
166   e->e.opr[1] = x;
167   e->e.opr[2] = 0;
168 
169   return e;
170 }
171 
172 /*****************************************************************************
173  *
174  * Create a two operand operator expression
175  *
176  * Parameters:
177  *     op		Operator code
178  *     l		Left-hand operand
179  *     r		Right-hand operand
180  *
181  * Returns:		Two operand operator expression.
182  *
183  *****************************************************************************/
new_Expr_op(exprcode_t op,Expr * l,Expr * r)184 Expr *new_Expr_op(exprcode_t op,Expr *l,Expr *r)
185 {
186   Expr *e = (Expr*) malloc(sizeof(Expr));
187 
188   e->e_type = op;
189   e->e.opr[0] = l;
190   e->e.opr[1] = r;
191   e->e.opr[2] = 0;
192 
193   return e;
194 }
195 
196 /*****************************************************************************
197  *
198  * Create a three operand operator expression (e.g. "a ? b : c")
199  *
200  * Parameters:
201  *     op		Operator code
202  *     l		Left-hand operand
203  *     m		Middle operand
204  *     r		Right-hand operand
205  *
206  * Returns:		Three operand operator expression.
207  *
208  *****************************************************************************/
new_Expr_op3(exprcode_t op,Expr * l,Expr * m,Expr * r)209 Expr *new_Expr_op3(exprcode_t op,Expr *l,Expr *m,Expr *r)
210 {
211   Expr *e = (Expr*) malloc(sizeof(Expr));
212 
213   e->e_type = op;
214   e->e.opr[0] = l;
215   e->e.opr[1] = m;
216   e->e.opr[2] = r;
217 
218   return e;
219 }
220 
221 /*****************************************************************************
222  *
223  * Create a repeating concat operator expression
224  *
225  * Parameters:
226  *     b		Number of replications (must evaluate to constant)
227  *     x		Expression to be replicated
228  *
229  * Returns:		Concatenated expression.
230  *
231  *****************************************************************************/
new_Expr_repcat(Expr * b,Expr * x)232 Expr *new_Expr_repcat(Expr *b,Expr *x)
233 {
234   Expr *e = (Expr*) malloc(sizeof(Expr));
235 
236   e->e_type = E_REPCAT;
237   e->e.opr[0] = b;
238   e->e.opr[1] = x;
239   e->e.opr[2] = 0;
240 
241   return e;
242 }
243 
244 /*****************************************************************************
245  *
246  * Create an expression for an unsized integer
247  *
248  * Parameters:
249  *     n		Integer to create expression from.
250  *
251  * Returns:		Integer value expression.
252  *
253  *****************************************************************************/
new_Expr_num(int n)254 Expr *new_Expr_num(int n)
255 {
256   Expr *e = (Expr*) malloc(sizeof(Expr));
257 
258   e->e_type = E_NUMBER;
259   e->e.snum = new_Value(SSWORDSIZE);
260   Value_convertI(e->e.snum,n);
261 
262   return e;
263 }
264 
265 /*****************************************************************************
266  *
267  * Create an expression for a float
268  *
269  * Parameters:
270  *     n		Integer to create expression from.
271  *
272  * Returns:		Integer value expression.
273  *
274  *****************************************************************************/
new_Expr_realnum(real_t n)275 Expr *new_Expr_realnum(real_t n)
276 {
277   Expr *e = (Expr*) malloc(sizeof(Expr));
278 
279   e->e_type = E_REAL;
280   e->e.snum = new_Value(SSWORDSIZE);
281   Value_convertR(e->e.snum,n);
282 
283   return e;
284 }
285 
286 /*****************************************************************************
287  *
288  * Create an expression for a sized value
289  *
290  * Parameters:
291  *     spec		Specification of sized value (e.g., "8'h3f")
292  *
293  * Returns:		Sized value expression.
294  *
295  *****************************************************************************/
new_Expr_hex(const char * spec)296 Expr *new_Expr_hex(const char *spec)
297 {
298   Expr *e = (Expr*) malloc(sizeof(Expr));
299 
300   e->e_type = E_HEX;
301   e->e.snum = new_Value(0);
302   if (Value_convert(e->e.snum,spec) != 0)
303     errorFile(Place_getCurrent(),ERR_BADVALUE,spec);
304 
305   return e;
306 }
307 
308 /*****************************************************************************
309  *
310  * Create an expression from a string.
311  *
312  * Parameters:
313  *     s		String to convert to expression
314  *
315  * Returns:		Expression representing string
316  *
317  *****************************************************************************/
new_Expr_str(const char * s)318 Expr *new_Expr_str(const char *s)
319 {
320   Expr *e = (Expr*) malloc(sizeof(Expr));
321 
322   e->e_type = E_HEX;
323   e->e.snum = new_Value(0);
324   Value_convertStr(e->e.snum,s);
325 
326   return e;
327 }
328 
329 /*****************************************************************************
330  *
331  * Free memory associated with an expression and all children.
332  *
333  * Parameters:
334  *     e		Expression to be freed.
335  *
336  *****************************************************************************/
delete_Expr(Expr * e)337 void delete_Expr(Expr *e)
338 {
339   int i;
340 
341   switch (e->e_type) {
342   case E_LITERAL :
343     free(Expr_getLitName(e));
344     break;
345   case E_HEX :
346     delete_Value(e->e.snum);
347     break;
348   case E_NUMBER :
349     break;
350   default :			/* Assumed to be an operator */
351     for (i = 0;i < 3;i++)
352       if (e->e.opr[i])
353 	delete_Expr(e->e.opr[i]);
354     break;
355   }
356 
357   free(e);
358 }
359 
360 
361 /*****************************************************************************
362  *
363  * Print internal part of a concatenation expression
364  *
365  * Parameters:
366  *     f		File on which to print
367  *     e		Expression to be printed
368  *
369  *****************************************************************************/
Expr_printCat(Expr * e,FILE * f)370 static void Expr_printCat(Expr *e,FILE *f)
371 {
372   if (e->e_type != E_CONCAT) {
373     Expr_print(e,f);
374     return;
375   }
376 
377   Expr_printCat(e->e.opr[0],f);
378   fprintf(f,",");
379   Expr_printCat(e->e.opr[1],f);
380 }
381 
382 /*****************************************************************************
383  *
384  * Generate string of a concatenation expression
385  *
386  * Parameters:
387  *     p		String pointer to write to
388  *     e		Expression to be printed
389  *
390  *****************************************************************************/
Expr_getstrCat(Expr * e,char * p)391 static char *Expr_getstrCat(Expr *e,char *p)
392 {
393   if (e->e_type != E_CONCAT) {
394     p = Expr_getstr(e,p);
395     return p;
396   }
397 
398   p = Expr_getstrCat(e->e.opr[0],p);
399   p += sprintf(p,",");
400   p = Expr_getstrCat(e->e.opr[1],p);
401 
402   return p;
403 }
404 
405 /*****************************************************************************
406  *
407  * Generate a string with an expression
408  *
409  * Parameters:
410  *     p		String to write to.
411  *     e		Expression to be printed
412  *
413  *****************************************************************************/
Expr_getstr(Expr * e,char * p)414 char *Expr_getstr(Expr*e,char *p)
415 {
416   OpDesc *od = 0;
417 
418   if (!e) {
419     p+=sprintf(p,"<<null>>");
420     return p;
421   }
422 
423   /*
424    * Check for and print any non-operator or special operator (contatenation) expressions.
425    */
426   switch (e->e_type) {
427   case E_AT :
428     p+=sprintf(p,"@(");
429     if (e->e.opr[1])
430       p = Expr_getstr(e->e.opr[1],p);
431     else
432       p += sprintf(p,"*");
433     p += sprintf(p,")");
434     break;
435   case E_LITERAL :
436     p += sprintf(p,"%s",Expr_getLitName(e));
437     return p;
438   case E_NUMBER :
439   case E_HEX :
440     Value_getstr(e->e.snum,p);
441     p += strlen(p);
442     return p;
443   case E_REPCAT :
444     p += sprintf(p,"{");
445     p = Expr_getstr(e->e.opr[0],p);
446     if (e->e.opr[1]->e_type == E_CONCAT)
447       p = Expr_getstr(e->e.opr[1],p);		/* Omit braces if repeating a concat */
448     else {
449       p += sprintf(p,"{");
450       p = Expr_getstr(e->e.opr[1],p);
451       p += sprintf(p,"}");
452     }
453     p += sprintf(p,"}");
454     return p;
455   case E_CONCAT :
456     p += sprintf(p,"{");
457     p = Expr_getstrCat(e,p);
458     p += sprintf(p,"}");
459     return p;
460   case E_RANGE :
461   case E_VECTORP :
462   case E_VECTORN :
463     p = Expr_getstr(e->e.opr[0],p);
464     p += sprintf(p,"[");
465     p = Expr_getstr(e->e.opr[1],p);
466     if (e->e.opr[2]) {
467       if (e->e_type == E_RANGE)
468 	p += sprintf(p,":");
469       else if (e->e_type == E_VECTORP)
470 	p += sprintf(p,"+:");
471       else
472 	p += sprintf(p,"-:");
473 
474       p = Expr_getstr(e->e.opr[2],p);
475     }
476     p += sprintf(p,"]");
477     return p;
478   default:
479     break;
480   }
481 
482   od = OpDesc_find(e->e_type);
483   if (!od) {
484     p += sprintf(p,"[?]");			/* unknown expression type */
485     return p;
486   }
487 
488   if (od->od_nopr == 3) {
489     return p;
490   }
491 
492   if (e->e.opr[0]) {
493     OpDesc *opr_od = OpDesc_find(e->e.opr[0]->e_type);
494 
495     if (opr_od && opr_od->od_plev > od->od_plev) p += sprintf(p,"(");
496     p = Expr_getstr(e->e.opr[0],p);
497     if (opr_od && opr_od->od_plev > od->od_plev) p += sprintf(p,")");
498   }
499 
500   if (e->e.opr[1]) {
501     OpDesc *opr_od = OpDesc_find(e->e.opr[1]->e_type);
502 
503     if (od->od_plev >= TIGHT_LEVEL)
504       p += sprintf(p,"%s",od->od_text);
505     else
506       p += sprintf(p," %s ",od->od_text);
507 
508     if (opr_od && opr_od->od_plev > od->od_plev) p += sprintf(p,"(");
509     p = Expr_getstr(e->e.opr[1],p);
510     if (opr_od && opr_od->od_plev > od->od_plev) p += sprintf(p,")");
511   }
512 
513   if (e->e.opr[2]) {
514     OpDesc *opr_od = OpDesc_find(e->e.opr[2]->e_type);
515 
516     if (od->od_plev >= TIGHT_LEVEL)
517       p += sprintf(p,"%s",strend(od->od_text)+1);
518     else
519       p += sprintf(p," %s ",strend(od->od_text)+1);
520 
521     if (opr_od && opr_od->od_plev > od->od_plev) p += sprintf(p,"(");
522     p = Expr_getstr(e->e.opr[2],p);
523     if (opr_od && opr_od->od_plev > od->od_plev) p += sprintf(p,")");
524   }
525 
526   return p;
527 }
528 
529 /*****************************************************************************
530  *
531  * Print an expression
532  *
533  * Parameters:
534  *     f		File on which to print
535  *     e		Expression to be printed
536  *
537  *****************************************************************************/
Expr_print(Expr * e,FILE * f)538 void Expr_print(Expr*e,FILE *f)
539 {
540   OpDesc *od = 0;
541 
542   if (!e) {
543     fprintf(f,"<<null>>");
544     return;
545   }
546 
547   /*
548    * Check for and print any non-operator or special operator (contatenation) expressions.
549    */
550   switch (e->e_type) {
551   case E_AT :
552     fprintf(f,"@(");
553     if (e->e.opr[1])
554       Expr_print(e->e.opr[1],f);
555     else
556       fprintf(f,"*");
557     fprintf(f,")");
558     break;
559   case E_LITERAL :
560     fprintf(f,"%s",Expr_getLitName(e));
561     return;
562   case E_NUMBER :
563   case E_HEX :
564     Value_print(e->e.snum,f);
565     return;
566   case E_REPCAT :
567     fprintf(f,"{");
568     Expr_print(e->e.opr[0],f);
569     if (e->e.opr[1]->e_type == E_CONCAT)
570       Expr_print(e->e.opr[1],f);		/* Omit braces if repeating a concat */
571     else {
572       fprintf(f,"{");
573       Expr_print(e->e.opr[1],f);
574       fprintf(f,"}");
575     }
576     fprintf(f,"}");
577     return;
578   case E_CONCAT :
579     fprintf(f,"{");
580     Expr_printCat(e,f);
581     fprintf(f,"}");
582     return;
583   case E_RANGE :
584   case E_VECTORP :
585   case E_VECTORN :
586     Expr_print(e->e.opr[0],f);
587     fprintf(f,"[");
588     Expr_print(e->e.opr[1],f);
589     if (e->e.opr[2]) {
590       if (e->e_type == E_RANGE)
591 	fprintf(f,":");
592       else if (e->e_type == E_VECTORP)
593 	fprintf(f,"+:");
594       else
595 	fprintf(f,"-:");
596 
597       Expr_print(e->e.opr[2],f);
598     }
599     fprintf(f,"]");
600     return;
601   case E_DELAY :
602     fprintf(f,"#");
603     if (e->e.opr[DT_MIN]) {
604       Expr_print(e->e.opr[DT_MIN],f);
605       fprintf(f,":");
606       Expr_print(e->e.opr[DT_TYP],f);
607       fprintf(f,":");
608       Expr_print(e->e.opr[DT_MAX],f);
609     } else
610       Expr_print(e->e.opr[DT_TYP],f);
611     return;
612   default:
613     break;
614   }
615 
616   od = OpDesc_find(e->e_type);
617   if (!od) {
618     fprintf(f,"[?]");			/* unknown expression type */
619     return;
620   }
621 
622   if (od->od_nopr == 3) {
623     return;
624   }
625 
626   if (e->e.opr[0]) {
627     OpDesc *opr_od = OpDesc_find(e->e.opr[0]->e_type);
628 
629     if (opr_od && opr_od->od_plev > od->od_plev) fprintf(f,"(");
630     Expr_print(e->e.opr[0],f);
631     if (opr_od && opr_od->od_plev > od->od_plev) fprintf(f,")");
632   }
633 
634   if (e->e.opr[1]) {
635     OpDesc *opr_od = OpDesc_find(e->e.opr[1]->e_type);
636 
637     if (od->od_plev >= TIGHT_LEVEL)
638       fprintf(f,"%s",od->od_text);
639     else
640       fprintf(f," %s ",od->od_text);
641 
642     if (opr_od && opr_od->od_plev > od->od_plev) fprintf(f,"(");
643     Expr_print(e->e.opr[1],f);
644     if (opr_od && opr_od->od_plev > od->od_plev) fprintf(f,")");
645   }
646 
647   if (e->e.opr[2]) {
648     OpDesc *opr_od = OpDesc_find(e->e.opr[2]->e_type);
649 
650     if (od->od_plev >= TIGHT_LEVEL)
651       fprintf(f,"%s",strend(od->od_text)+1);
652     else
653       fprintf(f," %s ",strend(od->od_text)+1);
654 
655     if (opr_od && opr_od->od_plev > od->od_plev) fprintf(f,"(");
656     Expr_print(e->e.opr[2],f);
657     if (opr_od && opr_od->od_plev > od->od_plev) fprintf(f,")");
658   }
659 }
660 
661 /*****************************************************************************
662  *
663  * Return a range
664  *
665  * Parameters:
666  *     msb		Most significant bit expression.
667  *     lsb		Least significant bit expression.
668  *
669  *****************************************************************************/
new_VRange(rangestyle_t rs,Expr * left,Expr * right)670 VRange *new_VRange(rangestyle_t rs,Expr *left,Expr *right)
671 {
672   VRange *r = (VRange*) malloc(sizeof(VRange));
673 
674   r->vr_style = rs;
675   r->vr_left = left;
676   r->vr_right = right;
677 
678   return r;
679 }
680 
delete_VRange(VRange * r,int recursive)681 void delete_VRange(VRange *r, int recursive)
682 {
683   if (recursive) {
684     if (r->vr_left) delete_Expr(r->vr_left);
685     if (r->vr_right) delete_Expr(r->vr_right);
686   }
687   free(r);
688 }
689 
690 
691 /*****************************************************************************
692  *
693  * Print a range
694  *
695  * Parameters:
696  *     r		Range to print
697  *     f		File on which to print
698  *
699  *****************************************************************************/
VRange_print(VRange * r,FILE * f)700 void VRange_print(VRange *r,FILE *f)
701 {
702   if (!r) return;
703 
704   if (r->vr_style == RS_AUTO) {
705     fprintf(f,"[*]");
706     return;
707   }
708 
709 
710   fprintf(f,"[");
711   Expr_print(r->vr_left, f);
712   if (r->vr_style != RS_SINGLE) {
713     if (r->vr_style == RS_BASEUP)
714       fprintf(f,"+:");
715     else if (r->vr_style == RS_BASEDN)
716       fprintf(f,"-:");
717     else
718       fprintf(f,":");
719 
720     Expr_print(r->vr_right, f);
721   }
722   fprintf(f,"]");
723 }
724 
725 /*****************************************************************************
726  *
727  * Print a range that is directly specified with numbers.
728  *
729  * Parameters:
730  *     r		Range to print
731  *     f		File on which to print
732  *
733  *****************************************************************************/
VRange_getDirect(VRange * r,char * buf)734 int VRange_getDirect(VRange *r,char *buf)
735 {
736   unsigned size;
737 
738   if (VRange_getSize(r, 0, &size) < 0) {
739     sprintf(buf,"0:0");
740     return -1;
741   }
742 
743   sprintf(buf,"%u:0",size-1);
744   return 0;
745 }
746 
747 
748 /*****************************************************************************
749  *
750  * Get the LSB expression of a range
751  *
752  * Parameters:
753  *     r		Range to evaluate
754  *
755  * Returns:		Expression for LSB
756  *
757  *****************************************************************************/
VRange_getLsb(VRange * r)758 Expr *VRange_getLsb(VRange *r)
759 {
760   switch (r->vr_style) {
761   case RS_SINGLE :
762   case RS_BASEUP :
763   case RS_BASEDN :
764     return r->vr_left;
765   case RS_MAXMIN :
766     return r->vr_right;
767   case RS_AUTO :
768     return 0;
769   }
770   return 0;
771 }
772 
773 /*****************************************************************************
774  *
775  * Evaluate constant expressions and return the MSB of a range.
776  *
777  * Parameters:
778  *     r		Range to evaluate
779  *     scope		Scope for variable lookup
780  *     *msb		Returns msb here.
781  *
782  *****************************************************************************/
VRange_parmEvalMsb(VRange * r,Scope * scope,unsigned * msb)783 int VRange_parmEvalMsb(VRange *r,Scope *scope,unsigned *msb)
784 {
785   switch (r->vr_style) {
786   case RS_SINGLE :
787   case RS_MAXMIN :
788   case RS_BASEDN :
789     return Expr_parmEvalI(r->vr_left,scope,msb,PEF_NONE);
790   case RS_BASEUP :
791     {
792       unsigned lsb,width;
793 
794       if (Expr_parmEvalI(r->vr_left,scope,&lsb,PEF_NONE) < 0) return -1;
795       if (Expr_parmEvalI(r->vr_right,scope,&width,PEF_NONE) < 0) return -1;
796       *msb = lsb + width -1;
797       return 0;
798     }
799   case RS_AUTO :
800     *msb =  Expr_getCollapsedBitSize(r->vr_left,scope)-1;
801     return 0;
802   }
803   return -1;
804 }
805 
806 /*****************************************************************************
807  *
808  * Evaluate constant expressions and return the LSB of a range.
809  *
810  * Parameters:
811  *     r		Range to evaluate
812  *     scope		Scope for variable lookup
813  *     *lsb		Returns lsb here.
814  *
815  *****************************************************************************/
VRange_parmEvalLsb(VRange * r,Scope * scope,unsigned * lsb)816 int VRange_parmEvalLsb(VRange *r,Scope *scope,unsigned *lsb)
817 {
818   switch (r->vr_style) {
819   case RS_SINGLE :
820   case RS_BASEUP :
821     return Expr_parmEvalI(r->vr_left,scope,lsb,PEF_NONE);
822   case RS_MAXMIN :
823     return Expr_parmEvalI(r->vr_right,scope,lsb,PEF_NONE);
824   case RS_BASEDN :
825     {
826       unsigned msb,width;
827 
828       if (Expr_parmEvalI(r->vr_left,scope,&msb,PEF_NONE) < 0) return -1;
829       if (Expr_parmEvalI(r->vr_right,scope,&width,PEF_NONE) < 0) return -1;
830       *lsb = msb + 1 - width;
831       return 0;
832     }
833   case RS_AUTO :
834     *lsb = 0;
835     return 0;
836   }
837   return 0;
838 }
839 
840 
VRange_getSize(VRange * r,Scope * scope,unsigned * width)841 int VRange_getSize(VRange *r,Scope *scope,unsigned *width)
842 {
843   if (!r) {
844     *width = 1;
845     return 0;
846   }
847 
848   switch (r->vr_style) {
849   case RS_SINGLE :
850     *width = 1;
851     break;
852   case RS_BASEUP :
853   case RS_BASEDN :
854     if (Expr_parmEvalI(r->vr_right,scope,width,PEF_NONE) < 0)
855       return -1;
856     break;
857   case RS_MAXMIN :
858     {
859       unsigned msb,lsb;
860 
861       if (Expr_parmEvalI(r->vr_left,scope,&msb,PEF_NONE) < 0) return -1;
862       if (Expr_parmEvalI(r->vr_right,scope,&lsb,PEF_NONE) < 0) return -1;
863       *width = msb - lsb + 1;
864     }
865     break;
866   case RS_AUTO :
867     *width =  Expr_getCollapsedBitSize(r->vr_left,scope);
868     return 0;
869   }
870 
871   return 0;
872 }
873 
874 
875 /*****************************************************************************
876  *
877  * Create a NameExpr object
878  *
879  * Parameters:
880  *     name		Name to associate with exression (or null)
881  *     e		Expression to name
882  *
883  *****************************************************************************/
new_NameExpr(const char * name,Expr * e)884 NameExpr *new_NameExpr(const char *name,Expr *e)
885 {
886   NameExpr *ne = (NameExpr*) malloc(sizeof(NameExpr));
887 
888   ne->ne_name = name ? strdup(name) : 0;
889   ne->ne_expr = e;
890 
891   return ne;
892 }
893 
894 /*****************************************************************************
895  *
896  * Evaluate a parameter expression when expecting an integer value.
897  *
898  * Parameters:
899  *     e		Expression to evaluate
900  *     scope		Scope for variable lookup
901  *     n		Evaluated value
902  *
903  * Returns:		Non-zero on error
904  *
905  * This function calls Expr_parmEval and tries to convert it to an integer.
906  * It returns non-zero if either of these steps fail.
907  *
908  *****************************************************************************/
Expr_parmEvalI(Expr * e,Scope * scope,unsigned * n,parmevflags_t flags)909 int Expr_parmEvalI(Expr *e,Scope *scope,unsigned *n,parmevflags_t flags)
910 {
911   Value *r = Expr_parmEval(e,scope,flags);
912   int rcode = 0;
913 
914   if (!r) return -1;
915   if (Value_toInt(r, n) < 0) {
916     rcode = -1;
917   }
918 
919   delete_Value(r);
920   return rcode;
921 }
922 
923 /*****************************************************************************
924  *
925  * Evaluate a parameter expression.
926  *
927  * Parameters:
928  *     e		Expression to evaluate
929  *     scope		Scope for variable lookup
930  *
931  * Returns:		Value value of expression (or null on error)
932  *
933  * This function is used to evaluate expressions that are expected to evaluate
934  * to a constant.  The constant can be either a sized value or an unsized value.
935  * These expressions are generally found in places such as delay values or
936  * bit ranges and can contain identifiers for constant values.
937  *
938  *
939  *****************************************************************************/
Expr_parmEval(Expr * e,Scope * scope,parmevflags_t flags)940 Value *Expr_parmEval(Expr *e,Scope *scope,parmevflags_t flags)
941 {
942   Value *r;
943 
944   if (!e) return 0;
945 
946   r = new_Value(0);
947 
948   switch (e->e_type) {
949   case E_NOT :
950   case E_UINV :
951   case E_UNEG :
952   case E_UAND :
953   case E_UOR :
954   case E_UXOR :
955   case E_UNAND :
956   case E_UNOR :
957   case E_UNXOR :
958   case E_MUL :
959   case E_DIV :
960   case E_MOD :
961   case E_ADD :
962   case E_SUB :
963   case E_RSHIFT :
964   case E_LSHIFT :
965   case E_ARSHIFT :
966   case E_ALSHIFT :
967   case E_GT :
968   case E_LT :
969   case E_GE :
970   case E_LE :
971   case E_EQ :
972   case E_NE :
973   case E_EQZ :
974   case E_NEZ :
975   case E_BAND :
976   case E_BNAND :
977   case E_BXOR :
978   case E_BNXOR :
979   case E_BOR :
980   case E_BNOR :
981   case E_AND :
982   case E_OR :
983   case E_QUEST :
984   case E_CONCAT :
985   case E_REPCAT :
986     {
987       Value *t[3];
988       int i;
989       OpDesc *od = OpDesc_find(e->e_type);
990       int sumsize = 0;
991       int maxsize = 1;
992 
993       if (!od) {
994 	errorFile(Place_getCurrent(),ERR_IE_NOOP);
995 	goto abortEval;
996       }
997 
998       for (i = 0;i < 3;i++) {
999 	if (e->e.opr[i]) {
1000 	  t[i] = Expr_parmEval(e->e.opr[i],scope,flags);
1001 	  if (!t[i]) goto abortEval;
1002 	  if (Value_nbits(t[i]) > maxsize) maxsize = Value_nbits(t[i]);
1003 	  sumsize += Value_nbits(t[i]);
1004 	} else
1005 	  t[i] = 0;
1006       }
1007 
1008       if ((od->od_nopr == 1 && !t[1])
1009 	  || (od->od_nopr == 2 && (!t[0] || !t[1]))
1010 	  || (od->od_nopr == 3 && (!t[0] || !t[1] || !t[2]))
1011 	  ) {
1012 	return 0;
1013       }
1014 
1015       switch (od->od_outSize) {
1016       case OS_MAX : Value_resize(r,maxsize); break;
1017       case OS_SUM : Value_resize(r,sumsize); break;
1018       default :	    Value_resize(r,1); break;
1019       }
1020 
1021       if ((*od->od_opfunc)(r,t[0],t[1],t[2]) != 0) {
1022 	errorFile(Place_getCurrent(),ERR_BADOP,od->od_text);
1023 	goto abortEval;
1024       }
1025 
1026       for (i = 0;i < 3;i++) {
1027       	if (t[i]) delete_Value(t[i]);
1028       }
1029     }
1030     break;
1031   case E_DELAY :
1032   case E_AT :			/* Illegal parameter expressions */
1033   case E_COND :
1034   case E_POSEDGE :
1035   case E_NEGEDGE :
1036   case E_EVENTOR :
1037   case E_TASK :
1038   case E_VECTORP :
1039   case E_VECTORN :
1040   case E_RANGE :
1041     errorFile(Place_getCurrent(),ERR_BADCONSTOP);
1042     goto abortEval;
1043     break;
1044   case E_LITERAL :		/* Look up as parameter */
1045     {
1046       Value *v;
1047 
1048       if (!scope)
1049 	goto abortEval;
1050 
1051       /*
1052        * If SPECPARM flag is set, try looking up this literal as a specify parameter.
1053        */
1054       if ((flags & PEF_SPECPARM)) {
1055 	ModuleInst *mi = Scope_getModuleInst(scope);
1056 	ModuleDecl *m = ModuleInst_getModDecl(mi);
1057 	Specify *spec = ModuleDecl_getSpecify(m);
1058 	int n;
1059 
1060 	if (Specify_getSpecParm(spec,Expr_getLitName(e),mi, &n) >= 0) {
1061 	  v =  new_Value(SSWORDSIZE);
1062 	  Value_convertI(v,n);
1063 	  return v;
1064 	}
1065       }
1066 
1067       v = Scope_findParm(scope,Expr_getLitName(e));
1068       if (v) {
1069 	Value_reinit(r,Value_nbits(v));
1070 	Value_copy(r,v);
1071       } else {
1072 	errorFile(Place_getCurrent(),ERR_NOTPARM,Expr_getLitName(e));
1073 	goto abortEval;
1074       }
1075     }
1076     break;
1077   case E_NUMBER :
1078   case E_HEX :
1079   case E_REAL :
1080     Value_reinit(r,Value_nbits(e->e.snum));
1081     Value_copy(r,e->e.snum);
1082     break;
1083   }
1084 
1085   return r;
1086 
1087  abortEval:
1088   delete_Value(r);
1089   return 0;
1090 }
1091 
1092 /*****************************************************************************
1093  *
1094  * Find the bit-size of a vector expression.
1095  *
1096  * Parameters:
1097  *     e		Expression to analyze.
1098  *     scope		Scope for variable lookup
1099  *
1100  * Returns:		Bit-size of expression.
1101  *
1102  * This function takes an expression like a[3] or m[3][5] and determines its
1103  * bit size.  Note that the meaning of something like a[3] depends on whether
1104  * a is a simple reg/net or a memory.
1105  *
1106  *****************************************************************************/
Expr_vectorGetSize(Expr * e,Scope * scope)1107 static int Expr_vectorGetSize(Expr *e, Scope *scope)
1108 {
1109   unsigned size;
1110   Net *n;
1111   VRange *addr, *bits;
1112 
1113   if (Expr_decodeVector(e,scope, &n, &addr, &bits) < 0) {
1114     return 0;
1115   }
1116 
1117   if (bits) {
1118     if (VRange_getSize(bits, scope, &size) < 0)
1119       size = 0;
1120   } else
1121     size = Net_nbits(n);
1122 
1123 
1124   if (addr) delete_VRange(addr, 0);
1125   if (bits) delete_VRange(bits, 0);
1126 
1127   return size;
1128 }
1129 
Expr_vectorGenerate(Expr * e,int nbits,Scope * scope,CodeBlock * cb)1130 static Value *Expr_vectorGenerate(Expr *e, int nbits, Scope *scope, CodeBlock *cb)
1131 {
1132   unsigned width;
1133   Value *src_value, *ret_value, *nLsb;
1134   VRange *addr, *bits;
1135   Net *n;
1136 
1137   if (Expr_decodeVector(e, scope, &n, &addr, &bits) < 0) {
1138     return 0;
1139   }
1140 
1141   if (addr) {
1142     Value *nAddr;
1143 
1144     src_value = new_Value(Net_nbits(n));
1145     nAddr = Expr_generate(VRange_getLsb(addr),SSWORDSIZE,scope,cb);
1146     BCMemFetch_init(CodeBlock_nextEmpty(cb),n,nAddr, src_value);
1147   } else
1148     src_value = Net_getValue(n);
1149 
1150 
1151   if (bits) {
1152     if (VRange_getSize(bits,scope,&width) < 0)
1153       return 0;
1154 
1155     nLsb = Expr_generate(VRange_getLsb(bits),SSWORDSIZE,scope,cb);
1156   } else {
1157     nLsb = 0;
1158     width = Net_nbits(n);
1159   }
1160 
1161   ret_value = new_Value(imax(nbits,width));
1162   Value_zero(ret_value);
1163 
1164 #if 0
1165   printf("BCCopyRange_generate: %s width=%d bits=(%p) ",Net_getName(n),width,bits);
1166   VRange_print(bits,stdout);
1167   printf("\n");
1168 #endif
1169 
1170   BCCopyRange_init(CodeBlock_nextEmpty(cb),ret_value,0,src_value,nLsb,width);
1171 
1172   if (bits) delete_VRange(bits, 0);
1173   if (addr) delete_VRange(addr, 0);
1174 
1175   return ret_value;
1176 }
1177 
1178 
1179 /*****************************************************************************
1180  *
1181  * Get the required bit size of an expression.
1182  *
1183  * Parameters:
1184  *     e		Expression to check.
1185  *     scope		Scope for variable lookup
1186  *
1187  *****************************************************************************/
Expr_getBitSize(Expr * e,Scope * scope)1188 int Expr_getBitSize(Expr *e,Scope *scope)
1189 {
1190   if (!e) return 0;
1191 
1192   switch (e->e_type) {
1193   case E_NOT :
1194   case E_UINV :
1195   case E_UNEG :
1196   case E_UAND :
1197   case E_UOR :
1198   case E_UXOR :
1199   case E_UNAND :
1200   case E_UNOR :
1201   case E_UNXOR :
1202   case E_MUL :
1203   case E_DIV :
1204   case E_MOD :
1205   case E_ADD :
1206   case E_SUB :
1207   case E_RSHIFT :
1208   case E_LSHIFT :
1209   case E_ARSHIFT :
1210   case E_ALSHIFT :
1211   case E_GT :
1212   case E_LT :
1213   case E_GE :
1214   case E_LE :
1215   case E_EQ :
1216   case E_NE :
1217   case E_EQZ :
1218   case E_NEZ :
1219   case E_BAND :
1220   case E_BNAND :
1221   case E_BXOR :
1222   case E_BNXOR :
1223   case E_BOR :
1224   case E_BNOR :
1225   case E_AND :
1226   case E_OR :
1227   case E_QUEST :
1228     {
1229       int i;
1230       int size = 0;
1231       OpDesc *od = OpDesc_find(e->e_type);
1232 
1233       if (!od) {
1234 	errorFile(Place_getCurrent(),ERR_IE_NOOP);
1235 	return 0;
1236       }
1237 
1238       for (i = 0;i < 3;i++) {
1239 	int s;
1240 
1241 	if (!e->e.opr[i]) continue;
1242 	s = Expr_getBitSize(e->e.opr[i], scope);
1243 	if (s == 0) return 0;			/* There was a problem with a sub-expression */
1244 	if (s > size) size = s;
1245       }
1246       return size;
1247     }
1248   case E_CONCAT :
1249     {
1250       int i;
1251       int size = 0;
1252       OpDesc *od = OpDesc_find(e->e_type);
1253 
1254       if (!od) {
1255 	errorFile(Place_getCurrent(),ERR_IE_NOOP);
1256 	return 0;
1257       }
1258 
1259       for (i = 0;i < 3;i++) {
1260 	int s;
1261 
1262 	if (!e->e.opr[i]) continue;
1263 	s = Expr_getBitSize(e->e.opr[i], scope);
1264 	if (s == 0) return 0;			/* There was a problem with a sub-expression */
1265 	size += s;
1266       }
1267       return size;
1268     }
1269     break;
1270   case E_REPCAT :
1271     {
1272       unsigned reps,size;
1273 
1274       if (Expr_parmEvalI(e->e.opr[0],scope,&reps,PEF_NONE) < 0) return 0;
1275       size = Expr_getBitSize(e->e.opr[1],scope);
1276       return reps*size;
1277     }
1278     break;
1279   case E_AT :					/* Not allowed in regular expressions */
1280   case E_COND :
1281   case E_DELAY :
1282   case E_POSEDGE :
1283   case E_NEGEDGE :
1284   case E_EVENTOR :
1285     errorFile(Place_getCurrent(),ERR_BADXOP);
1286     return 0;
1287     break;
1288   case E_RANGE :
1289   case E_VECTORP :
1290   case E_VECTORN :
1291     return Expr_vectorGetSize(e, scope);
1292   case E_LITERAL :
1293     {
1294       Net *n =  Scope_findNet(scope, Expr_getLitName(e),0);
1295       if (n) {
1296 	return Value_nbits(Net_getValue(n));
1297       } else {
1298 	errorFile(Place_getCurrent(),ERR_NOTDEF,Expr_getLitName(e));
1299 	return 0;
1300       }
1301     }
1302     break;
1303   case E_TASK :
1304     {
1305       UserTask *ut = ModuleInst_findTask(Scope_getModuleInst(scope),Expr_getLitName(e));
1306       if (ut) {
1307 	return UserTask_nbits(ut);
1308       }
1309     }
1310   case E_NUMBER :
1311     return SSWORDSIZE;
1312   case E_HEX :
1313     return Value_nbits(e->e.snum);
1314   case E_REAL :
1315     return SSREALSIZE;
1316   }
1317 
1318   return 0;
1319 }
1320 
1321 /*****************************************************************************
1322  *
1323  * Get the required bit size of an expression except that operators that
1324  * reduce the bit size to a single bit return a bit size of 1.
1325  *
1326  * Parameters:
1327  *     e		Expression to check.
1328  *     scope		Scope for varaible lookup
1329  *
1330  *****************************************************************************/
Expr_getCollapsedBitSize(Expr * e,Scope * scope)1331 int Expr_getCollapsedBitSize(Expr *e,Scope *scope)
1332 {
1333   if (!e) return 0;
1334 
1335   switch (e->e_type) {
1336   case E_NOT :
1337   case E_GT :
1338   case E_LT :
1339   case E_GE :
1340   case E_LE :
1341   case E_EQ :
1342   case E_NE :
1343   case E_EQZ :
1344   case E_NEZ :
1345   case E_AND :
1346   case E_OR :
1347     return 1;
1348   case E_UINV :
1349   case E_UNEG :
1350   case E_UAND :
1351   case E_UOR :
1352   case E_UXOR :
1353   case E_UNAND :
1354   case E_UNOR :
1355   case E_UNXOR :
1356   case E_MUL :
1357   case E_DIV :
1358   case E_MOD :
1359   case E_ADD :
1360   case E_SUB :
1361   case E_RSHIFT :
1362   case E_LSHIFT :
1363   case E_ARSHIFT :
1364   case E_ALSHIFT :
1365   case E_BAND :
1366   case E_BNAND :
1367   case E_BXOR :
1368   case E_BNXOR :
1369   case E_BOR :
1370   case E_BNOR :
1371   case E_QUEST :
1372     {
1373       int i;
1374       int size = 0;
1375       OpDesc *od = OpDesc_find(e->e_type);
1376 
1377       if (!od) {
1378 	errorFile(Place_getCurrent(),ERR_IE_NOOP);
1379 	return 0;
1380       }
1381 
1382       for (i = 0;i < 3;i++) {
1383 	int s;
1384 
1385 	if (!e->e.opr[i]) continue;
1386 	s = Expr_getCollapsedBitSize(e->e.opr[i],scope);
1387 	if (s == 0) return 0;			/* There was a problem with a sub-expression */
1388 	if (s > size) size = s;
1389       }
1390       return size;
1391     }
1392   case E_CONCAT :
1393     {
1394       int i;
1395       int size = 0;
1396       OpDesc *od = OpDesc_find(e->e_type);
1397 
1398       if (!od) {
1399 	errorFile(Place_getCurrent(),ERR_IE_NOOP);
1400 	return 0;
1401       }
1402 
1403       for (i = 0;i < 3;i++) {
1404 	int s;
1405 
1406 	if (!e->e.opr[i]) continue;
1407 	s = Expr_getCollapsedBitSize(e->e.opr[i],scope);
1408 	if (s == 0) return 0;			/* There was a problem with a sub-expression */
1409 	size += s;
1410       }
1411       return size;
1412     }
1413     break;
1414   case E_REPCAT :
1415     {
1416       unsigned reps,size;
1417 
1418       if (Expr_parmEvalI(e->e.opr[0],scope,&reps,PEF_NONE) < 0) return 0;
1419       size = Expr_getCollapsedBitSize(e->e.opr[1],scope);
1420       return reps*size;
1421     }
1422     break;
1423   case E_AT :					/* Not allowed in regular expressions */
1424   case E_COND :
1425   case E_DELAY :
1426   case E_POSEDGE :
1427   case E_NEGEDGE :
1428   case E_EVENTOR :
1429     errorFile(Place_getCurrent(),ERR_BADXOP);
1430     return 0;
1431     break;
1432   case E_RANGE :
1433   case E_VECTORP :
1434   case E_VECTORN :
1435     return Expr_vectorGetSize(e, scope);
1436   case E_LITERAL :
1437     {
1438       Net *n =  Scope_findNet(scope,Expr_getLitName(e),0);
1439       if (n) {
1440 	return Value_nbits(Net_getValue(n));
1441       } else {
1442 	errorFile(Place_getCurrent(),ERR_NOTDEF,Expr_getLitName(e));
1443 	return 0;
1444       }
1445     }
1446     break;
1447   case E_TASK :
1448     {
1449       UserTask *ut = ModuleInst_findTask(Scope_getModuleInst(scope),Expr_getLitName(e));
1450       if (ut) {
1451 	return UserTask_nbits(ut);
1452       }
1453     }
1454   case E_NUMBER :
1455   case E_REAL :
1456     return SSREALSIZE;
1457   case E_HEX :
1458     return Value_nbits(e->e.snum);
1459   }
1460 
1461   return 0;
1462 }
1463 
1464 /*****************************************************************************
1465  *
1466  * Generate byte code to evaluate an expression in the natural bit-size of e.
1467  *
1468  * Parameters:
1469  *     e		Expression for which to generate byte code
1470  *     scope		Scope to use for variables
1471  *     cb		Code block in which to write bytecode
1472  *
1473  * Returns:		Value with value of expression
1474  *
1475  *****************************************************************************/
Expr_generateS(Expr * e,Scope * scope,CodeBlock * cb)1476 Value *Expr_generateS(Expr *e,Scope *scope,CodeBlock *cb)
1477 {
1478   int nbits = Expr_getBitSize(e, scope);
1479   if (nbits <= 0) return 0;
1480   return Expr_generate(e, nbits, scope, cb);
1481 }
1482 
1483 
1484 /*****************************************************************************
1485  *
1486  * Generate byte code to evaluate an expression
1487  *
1488  * Parameters:
1489  *     e		Expression for which to generate byte code
1490  *     nbits		Bitsize of expression
1491  *     Scope		Scope to use for variables
1492  *     cb		Code block in which to write bytecode
1493  *
1494  * Returns:		Value with value of expression
1495  *
1496  *****************************************************************************/
Expr_generate(Expr * e,int nbits,Scope * scope,CodeBlock * cb)1497 Value *Expr_generate(Expr *e,int nbits,Scope *scope,CodeBlock *cb)
1498 {
1499   if (!e) return 0;
1500 
1501   switch (e->e_type) {
1502   case E_NOT :
1503   case E_UINV :
1504   case E_UNEG :
1505   case E_UAND :
1506   case E_UOR :
1507   case E_UXOR :
1508   case E_UNAND :
1509   case E_UNOR :
1510   case E_UNXOR :
1511   case E_MUL :
1512   case E_DIV :
1513   case E_MOD :
1514   case E_ADD :
1515   case E_SUB :
1516   case E_RSHIFT :
1517   case E_LSHIFT :
1518   case E_ARSHIFT :
1519   case E_ALSHIFT :
1520   case E_GT :
1521   case E_LT :
1522   case E_GE :
1523   case E_LE :
1524   case E_EQ :
1525   case E_NE :
1526   case E_EQZ :
1527   case E_NEZ :
1528   case E_BAND :
1529   case E_BNAND :
1530   case E_BXOR :
1531   case E_BNXOR :
1532   case E_BOR :
1533   case E_BNOR :
1534   case E_AND :
1535   case E_OR :
1536   case E_QUEST :
1537     {
1538       int i;
1539       OpDesc *od = OpDesc_find(e->e_type);
1540       Value *temp_s[3];
1541       Value *lhs;
1542       int has_real = 0;
1543 
1544       if (!od) return 0;
1545 
1546       for (i = 0;i < 3;i++) {
1547 	if (e->e.opr[i]) {
1548 	  temp_s[i] = Expr_generate(e->e.opr[i],nbits,scope,cb);
1549 	  if (Value_isReal(temp_s[i])) {
1550 	    has_real = 1;
1551 	  }
1552 	} else
1553 	  temp_s[i] = 0;
1554       }
1555 
1556       /*
1557        * Generate byte code for this operations.  If the operands are less than or
1558        * equal to the native word size on this machine, use the more efficient
1559        * version optimized for single word operands if it is available.
1560        */
1561       lhs = new_Value(nbits);
1562       if (has_real && od->od_f_opfunc) {
1563 	BCOpr_init(CodeBlock_nextEmpty(cb),od->od_f_opfunc,lhs,temp_s[0],temp_s[1],temp_s[2]);
1564 	if (od->od_outSize == OS_MAX) {
1565 	  lhs->flags = (ValueFlags)(lhs->flags | SF_REAL);
1566 	}
1567       } else if (nbits <= SSWORDSIZE && od->od_w_opfunc)
1568 	BCOpr_init(CodeBlock_nextEmpty(cb),od->od_w_opfunc,lhs,temp_s[0],temp_s[1],temp_s[2]);
1569       else
1570 	BCOpr_init(CodeBlock_nextEmpty(cb),od->od_opfunc,lhs,temp_s[0],temp_s[1],temp_s[2]);
1571 
1572       return lhs;
1573     }
1574     break;
1575   case E_CONCAT :
1576     {
1577       int i;
1578       OpDesc *od = OpDesc_find(e->e_type);
1579       Value *temp_s[3];
1580       Value *lhs;
1581 
1582       if (!od) return 0;
1583 
1584       for (i = 0;i < 3;i++) {
1585 	if (e->e.opr[i]) {
1586 	  temp_s[i] = Expr_generateS(e->e.opr[i],scope,cb);
1587 	}else
1588 	  temp_s[i] = 0;
1589       }
1590       lhs = new_Value(nbits);
1591       BCOpr_init(CodeBlock_nextEmpty(cb),od->od_opfunc,lhs,temp_s[0],temp_s[1],temp_s[2]);
1592 
1593       return lhs;
1594     }
1595     break;
1596   case E_REPCAT :
1597     {
1598       OpDesc *od = OpDesc_find(e->e_type);
1599       Value *temp_s[2];
1600       Value *lhs;
1601 
1602       if (!od) return 0;
1603 
1604       temp_s[0] = Expr_generateS(e->e.opr[0],scope,cb);
1605       temp_s[1] = Expr_generateS(e->e.opr[1],scope,cb);
1606 
1607       lhs = new_Value(nbits);
1608       BCOpr_init(CodeBlock_nextEmpty(cb),od->od_opfunc,lhs,temp_s[0],temp_s[1],0);
1609 
1610       return lhs;
1611     }
1612     break;
1613   case E_AT :					/* Not allowed in regular expressions */
1614   case E_COND :
1615   case E_DELAY :
1616   case E_POSEDGE :
1617   case E_NEGEDGE :
1618   case E_EVENTOR :
1619     errorFile(Place_getCurrent(),ERR_BADXOP);
1620     return 0;
1621   case E_LITERAL :				/* Look up as parameter */
1622     {
1623       Net *n =  Scope_findNet(scope,Expr_getLitName(e),0);
1624       Value *lhs;
1625 
1626       if (!n) return 0;
1627 
1628       if ((Net_getType(n) & NT_P_MEMORY)) {
1629 	errorFile(Place_getCurrent(),ERR_BADARRAYUSG,Expr_getLitName(e));
1630 	return 0;
1631       }
1632 
1633 
1634       if (Value_nbits(Net_getValue(n)) == nbits)
1635 	return Net_getValue(n);
1636       else {
1637 	lhs = new_Value(nbits);
1638 	BCCopy_init(CodeBlock_nextEmpty(cb),lhs,Net_getValue(n));
1639 	return lhs;
1640       }
1641     }
1642     break;
1643   case E_RANGE :
1644   case E_VECTORP :
1645   case E_VECTORN :
1646     return Expr_vectorGenerate(e, nbits, scope, cb);
1647   case E_TASK :
1648     {
1649       UserTask *ut = ModuleInst_findTask(Scope_getModuleInst(scope),Expr_getLitName(e));
1650       SysTaskDescript *func = SysTask_findEnt(e->e.task.name);
1651       void **sargs = 0;
1652       Value *lhs;
1653       int i;
1654       int offset = ut ? 1 : 0;
1655 
1656       if (e->e.task.argc+offset > 0) {
1657 	sargs = (void**) malloc((e->e.task.argc+offset)*sizeof(void*));
1658 	for (i = 0;i < e->e.task.argc;i++)
1659 	  sargs[i+offset] = Expr_generateS(e->e.task.argv[i],scope,cb);
1660       }
1661 
1662       if (ut) {
1663 	if (UserTask_getType(ut) != UTT_FUNCTION) {
1664 	  errorFile(Place_getCurrent(),ERR_TASKASFUNC,Expr_getLitName(e));
1665 	  return 0;
1666 	}
1667 	sargs[0] = lhs = new_Value(UserTask_nbits(ut));
1668 	if (UserTask_isAuto(ut))
1669 	  UserTask_generateInlineCall(ut,sargs,cb);
1670 	else
1671 	  UserTask_generateCall(ut,sargs,cb);
1672       } else if (func) {
1673 
1674 	if (e->e.task.argc < func->st_minArgs || e->e.task.argc > func->st_maxArgs) {
1675 	  errorFile(Place_getCurrent(),ERR_TASKARGS,e->e.task.name);
1676 	  return 0;
1677 	}
1678 
1679 	lhs = new_Value(nbits);
1680 	BCTask_init(CodeBlock_nextEmpty(cb),func->st_func,0,lhs,e->e.task.argc,sargs);
1681       } else {
1682 	errorFile(Place_getCurrent(),ERR_NOTASK,e->e.task.name);
1683 	lhs = 0;
1684       }
1685       return lhs;
1686     }
1687     break;
1688   case E_NUMBER :
1689   case E_HEX :
1690     {
1691       if (Value_nbits(e->e.snum) == nbits)
1692 	return e->e.snum;
1693       else {						/* Resize constant if not of requested size */
1694 	Value *lhs;
1695 
1696 	lhs = new_Value(nbits);
1697 	Value_zero(lhs);
1698 	Value_copyRange(lhs,0,e->e.snum,Value_nbits(e->e.snum)-1,0);
1699 	return lhs;
1700       }
1701     }
1702     break;
1703   case E_REAL :
1704     {
1705       if (Value_nbits(e->e.snum) == nbits)
1706 	return e->e.snum;
1707       else {						/* Resize constant if not of requested size */
1708 	Value *lhs;
1709 
1710 	lhs = new_Value(nbits);
1711 	Value_zero(lhs);
1712 	Value_copyRange(lhs,0,e->e.snum,Value_nbits(e->e.snum)-1,0);
1713 	lhs->flags = (ValueFlags)(lhs->flags & ~SF_REAL);
1714 	return lhs;
1715       }
1716     }
1717     break;
1718   }
1719 
1720   return 0;
1721 }
1722 
1723 /*****************************************************************************
1724  *
1725  * Get the set of nets that are read by an expression
1726  *
1727  *****************************************************************************/
Expr_getReaders(Expr * e,Scope * scope,PHash * H)1728 void Expr_getReaders(Expr*e, Scope *scope, PHash *H)
1729 {
1730   if (!e) return;
1731 
1732   switch (e->e_type) {
1733   case E_NOT :
1734   case E_UINV :
1735   case E_UNEG :
1736   case E_UAND :
1737   case E_UOR :
1738   case E_UXOR :
1739   case E_UNAND :
1740   case E_UNOR :
1741   case E_UNXOR :
1742   case E_MUL :
1743   case E_DIV :
1744   case E_MOD :
1745   case E_ADD :
1746   case E_SUB :
1747   case E_RSHIFT :
1748   case E_LSHIFT :
1749   case E_ARSHIFT :
1750   case E_ALSHIFT :
1751   case E_GT :
1752   case E_LT :
1753   case E_GE :
1754   case E_LE :
1755   case E_EQ :
1756   case E_NE :
1757   case E_EQZ :
1758   case E_NEZ :
1759   case E_BAND :
1760   case E_BNAND :
1761   case E_BXOR :
1762   case E_BNXOR :
1763   case E_BOR :
1764   case E_BNOR :
1765   case E_AND :
1766   case E_OR :
1767   case E_QUEST :
1768   case E_CONCAT :
1769   case E_REPCAT :
1770     {
1771       int i;
1772       OpDesc *od = OpDesc_find(e->e_type);
1773 
1774       if (!od) break;
1775 
1776       for (i = 0;i < 3;i++) {
1777 	if (e->e.opr[i])
1778 	  Expr_getReaders(e->e.opr[i], scope, H);
1779       }
1780     }
1781     break;
1782   case E_AT :					/* Not allowed in regular expressions */
1783   case E_COND :
1784   case E_DELAY :
1785   case E_POSEDGE :
1786   case E_NEGEDGE :
1787   case E_EVENTOR :
1788     break;
1789   case E_VECTORP :
1790   case E_VECTORN :
1791   case E_RANGE :
1792     Expr_getReaders(e->e.opr[0], scope, H);
1793     Expr_getReaders(e->e.opr[1], scope, H);
1794     if (e->e.opr[2])
1795       Expr_getReaders(e->e.opr[2], scope, H);
1796     break;
1797   case E_LITERAL :				/* Look up as parameter */
1798     if (scope) {
1799       Net *n;
1800 
1801       n =  Scope_findNet(scope,Expr_getLitName(e),0);
1802 
1803       if (!n) break;
1804 
1805       PHash_insert(H, n, n);
1806     } else {
1807       PHash_insert(H, e, e);
1808     }
1809     break;
1810   case E_TASK :
1811     {
1812       if (e->e.task.argc > 0) {
1813 	int i;
1814 
1815 	for (i = 0;i < e->e.task.argc;i++)
1816 	  Expr_getReaders(e->e.task.argv[i], scope, H);
1817       }
1818     }
1819     break;
1820   case E_NUMBER :
1821   case E_HEX :
1822   case E_REAL :
1823     break;
1824   }
1825 }
1826 
1827 /*****************************************************************************
1828  *
1829  * Get the set of literals that are read by an expression
1830  *
1831  *****************************************************************************/
Expr_getStaticReaders(Expr * e,SHash * H)1832 void Expr_getStaticReaders(Expr*e, SHash *H)
1833 {
1834   if (!e) return;
1835 
1836   switch (e->e_type) {
1837   case E_NOT :
1838   case E_UINV :
1839   case E_UNEG :
1840   case E_UAND :
1841   case E_UOR :
1842   case E_UXOR :
1843   case E_UNAND :
1844   case E_UNOR :
1845   case E_UNXOR :
1846   case E_MUL :
1847   case E_DIV :
1848   case E_MOD :
1849   case E_ADD :
1850   case E_SUB :
1851   case E_RSHIFT :
1852   case E_LSHIFT :
1853   case E_ARSHIFT :
1854   case E_ALSHIFT :
1855   case E_GT :
1856   case E_LT :
1857   case E_GE :
1858   case E_LE :
1859   case E_EQ :
1860   case E_NE :
1861   case E_EQZ :
1862   case E_NEZ :
1863   case E_BAND :
1864   case E_BNAND :
1865   case E_BXOR :
1866   case E_BNXOR :
1867   case E_BOR :
1868   case E_BNOR :
1869   case E_AND :
1870   case E_OR :
1871   case E_QUEST :
1872   case E_CONCAT :
1873   case E_REPCAT :
1874     {
1875       int i;
1876       OpDesc *od = OpDesc_find(e->e_type);
1877 
1878       if (!od) break;
1879 
1880       for (i = 0;i < 3;i++) {
1881 	if (e->e.opr[i])
1882 	  Expr_getStaticReaders(e->e.opr[i], H);
1883       }
1884     }
1885     break;
1886   case E_AT :					/* Not allowed in regular expressions */
1887   case E_COND :
1888   case E_DELAY :
1889   case E_POSEDGE :
1890   case E_NEGEDGE :
1891   case E_EVENTOR :
1892     break;
1893   case E_VECTORP :
1894   case E_VECTORN :
1895   case E_RANGE :
1896     Expr_getStaticReaders(e->e.opr[0], H);
1897     Expr_getStaticReaders(e->e.opr[1], H);
1898     if (e->e.opr[2])
1899       Expr_getStaticReaders(e->e.opr[2], H);
1900     break;
1901   case E_LITERAL :				/* Look up as parameter */
1902     if (e->e.literal.ishlit) {
1903       errorFile(Place_getCurrent(),ERR_BADHIER,e->e.literal.name);
1904       break;
1905     }
1906     SHash_insert(H, e->e.literal.name, e);
1907     break;
1908   case E_TASK :
1909     {
1910       if (e->e.task.argc > 0) {
1911 	int i;
1912 
1913 	for (i = 0;i < e->e.task.argc;i++)
1914 	  Expr_getStaticReaders(e->e.task.argv[i], H);
1915       }
1916     }
1917     break;
1918   case E_NUMBER :
1919   case E_HEX :
1920   case E_REAL :
1921     break;
1922   }
1923 }
1924 
1925 /*****************************************************************************
1926  *
1927  * Expand a concat expression into a list of expressions LSB first
1928  *
1929  * Parameters:
1930  *     e		Concat expression to expand
1931  *     scope		Scope for variable lookup
1932  *     clist		List of expressions
1933  *
1934  * Note: It is assumed that clist is initialized to empty before calling
1935  * this function.
1936  *
1937  *****************************************************************************/
Expr_expandConcat(Expr * e,Scope * scope,List * clist)1938 void Expr_expandConcat(Expr *e,Scope *scope,List *clist)
1939 {
1940   if (Expr_type(e) == E_CONCAT) {
1941     Expr_expandConcat(e->e.opr[1], scope, clist);
1942     Expr_expandConcat(e->e.opr[0], scope, clist);
1943   } else if (Expr_type(e) == E_REPCAT) {
1944     unsigned n;
1945     unsigned i;
1946 
1947     if (!scope) return;		/* repcats are ignored if no module instance given */
1948 
1949     if (Expr_parmEvalI(e->e.opr[0], scope,&n,PEF_NONE) < 0)
1950       return;
1951 
1952     for (i = 0;i < n;i++) {
1953       Expr_expandConcat(e->e.opr[1],scope,clist);
1954     }
1955   } else {
1956     List_addToTail(clist,e);
1957   }
1958 }
1959 
1960 
1961 /*****************************************************************************
1962  *
1963  * Convert a trigger expression into a list of triggers.
1964  *
1965  * Parameters:
1966  *     trigger		Trigger expression
1967  *     triggerList	Output list of triggers.
1968  *
1969  *****************************************************************************/
Expr_makeTriggerList(Expr * trigger,List * triggerList)1970 void Expr_makeTriggerList(Expr *trigger,List *triggerList)
1971 {
1972   if (!trigger) return;
1973 
1974   if (trigger->e_type == E_EVENTOR) {
1975     Expr_makeTriggerList(trigger->e.opr[0],triggerList);
1976     Expr_makeTriggerList(trigger->e.opr[1],triggerList);
1977     return;
1978   }
1979 
1980   List_addToTail(triggerList,trigger);
1981 }
1982 
1983 /*****************************************************************************
1984  *
1985  * Get the default trigger from a hash table containing all the readers.
1986  *
1987  *****************************************************************************/
Expr_getDefaultTriggerFromSet(PHash * P,Circuit * c)1988 Trigger *Expr_getDefaultTriggerFromSet(PHash *P,Circuit *c)
1989 {
1990   List posedges;
1991   List negedges;
1992   HashElem *he;
1993   Trigger *t;
1994 
1995   List_init(&posedges);
1996   List_init(&negedges);
1997 
1998   for (he = Hash_first(P);he;he = Hash_next(P, he)) {
1999     Net *n = (Net*) HashElem_obj(he);
2000     List_addToTail(&posedges, n);
2001     if (Net_nbits(n) == 1)
2002       List_addToTail(&negedges, n);
2003   }
2004 
2005   t = Circuit_getTrigger(c, &posedges, &negedges);
2006 
2007   List_uninit(&posedges);
2008   List_uninit(&negedges);
2009 
2010   return t;
2011 }
2012 
2013 /*****************************************************************************
2014  *
2015  * Get the default trigger for an expression (one that fires for any input)
2016  *
2017  * Parameters:
2018  *     e		Expression to examine
2019  *     scope		Scope to use for variable lookup
2020  *
2021  * Returns:		Trigger for the specified readerlist.
2022  *
2023  *****************************************************************************/
Expr_getDefaultTrigger(Expr * e,Scope * scope)2024 Trigger *Expr_getDefaultTrigger(Expr *e,Scope *scope)
2025 {
2026   PHash P;
2027   Trigger *t;
2028 
2029   if (!e) {
2030     errorFile(Place_getCurrent(),ERR_NONEXPCTL);
2031     return 0;
2032   }
2033 
2034   PHash_init(&P);
2035   Expr_getReaders(e, scope, &P);
2036   t = Expr_getDefaultTriggerFromSet(&P, &vgsim.vg_circuit);
2037   PHash_uninit(&P);
2038 
2039   return t;
2040 }
2041 
2042 /*****************************************************************************
2043  *
2044  * Convert a trigger expression into a trigger object.
2045  *
2046  * Parameters:
2047  *     trigger		Trigger expression.
2048  *     scope		Scope to use for variable lookup
2049  *     stat		Statment blocking condition modifies (used for "@(*)")
2050  *
2051  * Returns:		Trigger object or null on error.
2052  *
2053  *****************************************************************************/
Expr_getTrigger(Expr * trigger,Scope * scope,StatDecl * stat)2054 Trigger *Expr_getTrigger(Expr *trigger,Scope *scope, StatDecl *stat)
2055 {
2056   List triggerList;
2057   List posedges;
2058   List negedges;
2059   ListElem *le;
2060   Trigger *t = 0;
2061 
2062   /*
2063    * If "trigger" is null, then this is a @(*) trigger and we need to get the
2064    * event list from the modified statement.
2065    */
2066   if (!trigger) {
2067     PHash P;
2068     HashElem *he;
2069 
2070     if (!stat) {
2071       errorFile(Place_getCurrent(),ERR_NONSTATCTL);
2072       return 0;
2073     }
2074 
2075     PHash_init(&P);
2076     List_init(&posedges);
2077     List_init(&negedges);
2078 
2079     StatDecl_getReaders(stat, scope, &P);
2080 
2081     for (he = Hash_first(&P);he;he = Hash_next(&P, he)) {
2082       Net *n = (Net*) HashElem_obj(he);
2083       List_addToTail(&posedges, n);
2084       if (Net_nbits(n) == 1)
2085 	List_addToTail(&negedges, n);
2086     }
2087 
2088     t = Circuit_getTrigger(&vgsim.vg_circuit,&posedges,&negedges);
2089 
2090     PHash_uninit(&P);
2091     List_uninit(&posedges);
2092     List_uninit(&negedges);
2093     return t;
2094   }
2095 
2096   /*
2097    * Normal event trigger case starts here.
2098    */
2099   List_init(&triggerList);
2100   List_init(&posedges);
2101   List_init(&negedges);
2102 
2103   Expr_makeTriggerList(trigger,&triggerList);
2104 
2105   for (le = List_first(&triggerList);le;le = List_next(&triggerList,le)) {
2106     Expr *e = (Expr*) ListElem_obj(le);
2107     Net *n = 0;
2108     const char *name = 0;
2109     transtype_t transition = TT_NONE;
2110 
2111     if (Expr_type(e) == E_LITERAL) {
2112       transition = TT_EDGE;
2113       name = Expr_getLitName(e);
2114     } else if (Expr_type(e) == E_POSEDGE && Expr_type(e->e.opr[1]) == E_LITERAL) {
2115       transition = TT_POSEDGE;
2116       name = Expr_getLitName(e->e.opr[1]);
2117     } else if (Expr_type(e) == E_NEGEDGE && Expr_type(e->e.opr[1]) == E_LITERAL) {
2118       transition = TT_NEGEDGE;
2119       name = Expr_getLitName(e->e.opr[1]);
2120     } else {
2121       errorFile(Place_getCurrent(),ERR_BADEVENT);
2122       goto abortGen;
2123     }
2124 
2125     n = Scope_findNet(scope,name,0);
2126     if (!n) {
2127       errorFile(Place_getCurrent(),ERR_BADEVENTNET,name);
2128       goto abortGen;
2129     }
2130 
2131     if (Net_nbits(n) == 1) {
2132       if (transition == TT_POSEDGE || transition == TT_EDGE )
2133 	List_addToTail(&posedges,n);
2134       if (transition == TT_NEGEDGE || transition == TT_EDGE )
2135 	List_addToTail(&negedges,n);
2136     } else {
2137       /*
2138        * We only use the 'posedge' list for multi-bit wires and use that list
2139        * for all transitions.
2140        */
2141       if (transition != TT_EDGE) {
2142 	errorFile(Place_getCurrent(),ERR_BADEDGEEVENT,name);
2143 	goto abortGen;
2144       }
2145       List_addToTail(&posedges,n);
2146     }
2147   }
2148 
2149   t = Circuit_getTrigger(&vgsim.vg_circuit,&posedges,&negedges);
2150 
2151  abortGen:
2152   List_uninit(&triggerList);
2153   List_uninit(&posedges);
2154   List_uninit(&negedges);
2155 
2156   return t;
2157 }
2158 
2159 /*****************************************************************************
2160  *
2161  * Convert a delay value expression into an unsigned
2162  *
2163  * Parameters:
2164  *     delayExpr	Delay value expression.
2165  *     scope		Scope to use for variable lookup.
2166  *     ts		Timescale of delay
2167  *     *delay		Output delay value
2168  *
2169  * Returns:		Non-zero on error.
2170  *
2171  *****************************************************************************/
Expr_getDelay(Expr * delayExpr,Scope * scope,Timescale * ts,deltatime_t * delay)2172 int Expr_getDelay(Expr *delayExpr,Scope *scope,Timescale *ts, deltatime_t *delay)
2173 {
2174   Value *delay_value;
2175   Expr *e;
2176 
2177   e = delayExpr->e.opr[vgsim.vg_delayType];
2178   if (!e)
2179     e = delayExpr->e.opr[DT_TYP];
2180 
2181   delay_value = Expr_parmEval(e, scope,PEF_NONE);
2182 
2183   if (!delay_value) return -1;
2184 
2185   if (Value_isReal(delay_value)) {
2186     real_t r;
2187 
2188     Value_toReal(delay_value,&r);
2189     r *= ts->ts_units/ts->ts_precision;
2190     *delay = (deltatime_t) r;
2191     *delay *= ts->ts_precision/vgsim.vg_timescale.ts_precision;
2192   } else {
2193     Value_toTime(delay_value,delay);
2194     *delay *= ts->ts_units/vgsim.vg_timescale.ts_precision;
2195   }
2196 
2197   delete_Value(delay_value);
2198   return 0;
2199 }
2200 
2201 /*****************************************************************************
2202  *
2203  * Generate bytecode for a delay expression.
2204  *
2205  * Parameters:
2206  *     delay		Delay value expression
2207  *     scope		Scope to use for variable lookup
2208  *     cb		CodeBlock to use
2209  *
2210  *****************************************************************************/
Expr_generateDelay(Expr * delay,Scope * scope,CodeBlock * cb)2211 int Expr_generateDelay(Expr *delay, Scope *scope, CodeBlock *cb)
2212 {
2213   Timescale *ts = ModuleInst_getTimescale(CodeBlock_getModuleInst(cb));
2214   deltatime_t idelay;
2215 
2216   if (Expr_getDelay(delay,scope,ts,&idelay) != 0)
2217     return -1;
2218 
2219   BCDelay_init(CodeBlock_nextEmpty(cb),idelay);
2220 
2221   return 0;
2222 }
2223 
2224 /*****************************************************************************
2225  *
2226  * Generate bytecode for a trigger expression.
2227  *
2228  * Parameters:
2229  *     triggerExpr 	Trigger expression
2230  *     scope 		Scope to use for variable lookup.
2231  *     cb 		CodeBlock to use.
2232  *     stat		Statment blocking condition modifies (used for "@(*)")
2233  *
2234  *****************************************************************************/
Expr_generateTrigger(Expr * triggerExpr,Scope * scope,CodeBlock * cb,StatDecl * stat)2235 int Expr_generateTrigger(Expr *triggerExpr, Scope *scope, CodeBlock *cb, StatDecl *stat)
2236 {
2237   Trigger *t = 0;
2238 
2239   t = Expr_getTrigger(triggerExpr, scope, stat);
2240   if (!t) return -1;
2241 
2242   BCTrigger_init(CodeBlock_nextEmpty(cb),t);
2243 
2244   return 0;
2245 }
2246 
2247 /*****************************************************************************
2248  *
2249  * Generate a thread suspension with wakeup either by delay or trigger
2250  *
2251  * Parameter:
2252  *     econd		Expression for either a delay or trigger
2253  *     Scope		Scope to use for variable lookup
2254  *     cb		CodeBlock in which to generate bytecode.
2255  *     stat		Statment blocking condition modifies (used for "@(*)")
2256  *
2257  *****************************************************************************/
Expr_generateBCond(Expr * bcond,Scope * scope,CodeBlock * cb,StatDecl * stat)2258 int Expr_generateBCond(Expr *bcond, Scope *scope, CodeBlock *cb, StatDecl *stat)
2259 {
2260   if (Expr_type(bcond) == E_DELAY)
2261     return Expr_generateDelay(bcond, scope, cb);
2262   else if (Expr_type(bcond) == E_AT)
2263     return Expr_generateTrigger(bcond->e.opr[1], scope, cb,stat);
2264   else
2265     return -1;
2266 }
2267 
2268 /*****************************************************************************
2269  *
2270  * Decode an expression for a literal, memory access and/or bit select.
2271  *
2272  * Parameters:
2273  *     e		Expression with [] operator
2274  *     scope		Scope to use for variable lookup
2275  *     *n		Net that is being accessed.
2276  *     *addr		Address range
2277  *     *bits		Bit range
2278  *
2279  *****************************************************************************/
Expr_decodeVector(Expr * e,Scope * scope,Net ** n,VRange ** addr,VRange ** bits)2280 int Expr_decodeVector(Expr *e,Scope *scope,Net **n,VRange **addr,VRange **bits)
2281 {
2282   char *name = 0;
2283 
2284   *addr = 0;
2285   if (bits) *bits = 0;
2286 
2287   switch (Expr_type(e)) {
2288   case E_LITERAL :
2289     name = Expr_getLitName(e);
2290     *n =  Scope_findNet(scope, name,0);
2291 
2292     if (*n && (Net_getType(*n) & NT_P_MEMORY)) {
2293       errorFile(Place_getCurrent(),ERR_BADARRAYLHS,Expr_getLitName(e));
2294     }
2295 
2296     break;
2297   case E_VECTORP :
2298   case E_VECTORN :
2299   case E_RANGE :
2300     if (Expr_type(e->e.opr[0]) != E_LITERAL) {
2301       /*
2302        * We have multiple [].  Assume the next one in is an address, and
2303        * this is a bit select.
2304        */
2305       if (Expr_decodeVector(e->e.opr[0],scope,n,addr,0) < 0)
2306 	return -1;
2307     } else {
2308       /*
2309        * Single level of [].  Now lets see if it is a bit select or a memory reference.
2310        */
2311       name = Expr_getLitName(e->e.opr[0]);
2312       *n =  Scope_findNet(scope, name,0);
2313       if (!*n) break;		/* Failed to find net */
2314 
2315       /*
2316        * If this is a memory, create a VRange for the address lookup.
2317        */
2318       if ((Net_getType(*n) & NT_P_MEMORY)) {
2319 	if (e->e.opr[2]) {
2320 	  errorFile(Place_getCurrent(),ERR_BADARRAYRNG,name);
2321 	  return -1;
2322 	}
2323 
2324 	*addr = new_VRange(RS_SINGLE,e->e.opr[1],0);
2325 	break;
2326       }
2327     }
2328     if (bits) {
2329       /*
2330        * We are either the second level bit select off of a memory, or a first level
2331        * bit select off of a net if we get here.
2332        */
2333       switch (Expr_type(e)) {
2334       case E_VECTORP :
2335 	if (!e->e.opr[2])
2336 	  *bits = new_VRange(RS_SINGLE,e->e.opr[1],0);
2337 	else
2338 	  *bits = new_VRange(RS_BASEUP,e->e.opr[1],e->e.opr[2]);
2339 	break;
2340       case E_VECTORN :
2341 	*bits = new_VRange(RS_BASEDN,e->e.opr[1],e->e.opr[2]);
2342 	break;
2343       case E_RANGE :
2344 	*bits = new_VRange(RS_MAXMIN,e->e.opr[1],e->e.opr[2]);
2345 	break;
2346       default :
2347 	*bits = 0;
2348 	break;
2349       }
2350     }
2351     break;
2352   default :
2353     {
2354       char buf[STRMAX];
2355       sprintf(buf,"%d",Expr_type(e));
2356       errorFile(Place_getCurrent(),ERR_IE_BADEXP,buf);
2357     }
2358     return -1;
2359   }
2360 
2361 
2362   /*
2363    * A null net means we encountered an error looking up the net name.  Generate
2364    * an error and return -1.
2365    */
2366   if (!*n) {
2367     if (name) {
2368       errorFile(Place_getCurrent(),ERR_NOTDEF,name);
2369       return -1;
2370     } else {
2371       errorFile(Place_getCurrent(),ERR_IE_BADVAR,name);
2372       return -1;
2373     }
2374   }
2375 
2376   return 0;
2377 }
2378 
Expr_lhsGenerate(Expr * e,Scope * scope,CodeBlock * cb,Net ** n,Value ** nLsb,unsigned * size,Value ** nAddr)2379 int Expr_lhsGenerate(Expr *e,Scope *scope, CodeBlock *cb,Net **n,Value **nLsb,unsigned *size,Value **nAddr)
2380 {
2381   VRange *addr, *bits;
2382 
2383   if (Expr_decodeVector(e,scope, n, &addr, &bits) < 0) {
2384     return -1;
2385   }
2386 
2387   if (addr) {
2388     if (!nAddr) {
2389       return -1;
2390     }
2391     *nAddr = Expr_generate(VRange_getLsb(addr),SSWORDSIZE,scope,cb);
2392   } else {
2393     if (nAddr) *nAddr = 0;
2394   }
2395 
2396 
2397   if (bits) {
2398     if (VRange_getSize(bits, scope,size) < 0)
2399       return -1;
2400   } else
2401     *size = Net_nbits(*n);
2402 
2403   if (bits) {
2404     *nLsb = Expr_generate(VRange_getLsb(bits),SSWORDSIZE,scope,cb);
2405   } else
2406     *nLsb = 0;
2407 
2408   if (bits) delete_VRange(bits, 0);
2409   if (addr) delete_VRange(addr, 0);
2410 
2411   return 0;
2412 }
2413 
2414