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