Allow optimizer to replace params/locals in far space with registers for DS390 port
[fw/sdcc] / src / SDCCsymt.c
1 /*-------------------------------------------------------------------------
2   SDCCsymt.c - Code file for Symbols table related structures and MACRO's.              
3               Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 2, or (at your option) any
8    later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18    
19    In other words, you are welcome to use, share and improve this program.
20    You are forbidden to forbid anyone else to use, share and improve
21    what you give them.   Help stamp out software-hoarding!  
22 -------------------------------------------------------------------------*/
23
24 #include "common.h"
25
26 bucket   *SymbolTab [256]  ;  /* the symbol    table  */
27 bucket   *StructTab [256]  ;  /* the structure table  */
28 bucket   *TypedefTab[256]  ;  /* the typedef   table  */
29 bucket   *LabelTab  [256]  ;  /* the Label     table  */
30 bucket   *enumTab   [256]  ;  /* enumerated    table  */
31
32 extern   struct set *publics;
33
34 /*------------------------------------------------------------------*/
35 /* initSymt () - initialises symbol table related stuff             */
36 /*------------------------------------------------------------------*/
37 void  initSymt ()
38 {
39    int i = 0 ;
40
41    for ( i = 0 ; i < 256 ; i++ )
42       SymbolTab[i] = StructTab[i] = (void *) NULL ;
43    
44    
45 }
46 /*-----------------------------------------------------------------*/
47 /* newBucket - allocates & returns a new bucket                    */
48 /*-----------------------------------------------------------------*/
49 bucket   *newBucket ()
50 {
51         bucket *bp ;
52               
53         ALLOC(bp,sizeof(bucket));
54         
55         return bp ;
56 }
57
58 /*-----------------------------------------------------------------*/
59 /* hashKey - computes the hashkey given a symbol name              */
60 /*-----------------------------------------------------------------*/
61 int hashKey (const char *s)
62 {
63     unsigned long key = 0;
64
65     while (*s)
66         key += *s++ ;
67     return key % 256 ;
68 }
69
70 /*-----------------------------------------------------------------*/
71 /* addSym - adds a symbol to the hash Table                        */
72 /*-----------------------------------------------------------------*/
73 void  addSym ( bucket **stab , 
74                void *sym     , 
75                char *sname   , 
76                int level     , 
77                int block)
78 {
79     int i ;       /* index into the hash Table */
80     bucket   *bp ; /* temp bucket    *         */
81     
82     /* the symbols are always added at the head of the list  */
83     i = hashKey(sname) ;      
84     /* get a free entry */
85     ALLOC(bp,sizeof(bucket));
86     
87     bp->sym = sym ;     /* update the symbol pointer  */
88     bp->level = level;   /* update the nest level      */   
89     bp->block = block;
90     strcpy(bp->name,sname);     /* copy the name into place     */
91     
92     /* if this is the first entry */
93     if (stab[i] == NULL) {
94         bp->prev = bp->next = (void *) NULL ;  /* point to nothing */
95         stab[i] = bp ;
96     }
97     /* not first entry then add @ head of list */
98     else {       
99         bp->prev      = NULL ;
100         stab[i]->prev = bp ;
101         bp->next      = stab[i] ;
102         stab[i]       = bp ;
103     }
104 }
105
106 /*-----------------------------------------------------------------*/
107 /* deleteSym - deletes a symbol from the hash Table  entry         */
108 /*-----------------------------------------------------------------*/
109 void  deleteSym ( bucket **stab, void *sym, char *sname)
110 {
111     int i = 0 ;
112     bucket *bp ;
113     
114     i = hashKey(sname) ;
115     
116     bp = stab[i] ;
117     /* find the symbol */
118     while (bp) {
119         if (bp->sym == sym)  /* found it then break out */
120             break ;        /* of the loop             */
121         bp = bp->next ;
122     }
123     
124     if (!bp)   /* did not find it */
125         return ;
126     /* if this is the first one in the chain */
127     if ( ! bp->prev ) {
128         stab[i] = bp->next ;
129         if ( stab[i] ) /* if chain ! empty */
130             stab[i]->prev = (void *) NULL ;
131     }
132     /* middle || end of chain */
133     else {
134         if ( bp->next ) /* if not end of chain */
135             bp->next->prev = bp->prev ;
136         
137         bp->prev->next = bp->next ;
138     }
139     
140 }
141
142 /*-----------------------------------------------------------------*/
143 /* findSym - finds a symbol in a table                             */
144 /*-----------------------------------------------------------------*/
145 void  *findSym ( bucket **stab, void *sym, const char *sname)
146 {
147    bucket *bp ;
148
149    bp = stab[hashKey(sname)] ;
150    while (bp)
151    {
152       if ( bp->sym == sym || strcmp (bp->name,sname) == 0 )
153               break ;
154       bp = bp->next ;
155    }
156
157    return ( bp ? bp->sym : (void *) NULL ) ;
158 }
159
160 /*-----------------------------------------------------------------*/
161 /* findSymWithLevel - finds a symbol with a name & level           */
162 /*-----------------------------------------------------------------*/
163 void *findSymWithLevel ( bucket **stab, symbol *sym)
164 {
165   bucket *bp ;
166
167   bp = stab[hashKey(sym->name)];
168
169   /**
170    **  do the search from the head of the list since the 
171    **  elements are added at the head it is ensured that
172    ** we will find the deeper definitions before we find
173    ** the global ones. we need to check for symbols with 
174    ** level <= to the level given, if levels match then block
175    ** numbers need to match as well
176    **/
177   while (bp) {
178
179     if ( strcmp(bp->name,sym->name) == 0 && bp->level <= sym->level) {
180       /* if this is parameter then nothing else need to be checked */
181       if (((symbol *)(bp->sym))->_isparm)
182         return (bp->sym) ;
183       /* if levels match then block numbers hsould also match */
184       if (bp->level && bp->level == sym->level && bp->block == sym->block )
185               return ( bp->sym );
186       /* if levels don't match then we are okay */
187       if (bp->level && bp->level != sym->level)
188               return ( bp->sym );
189       /* if this is a global variable then we are ok too */
190       if (bp->level == 0 )
191               return (bp->sym);
192     }
193     
194     bp = bp->next; 
195   }
196
197   return (void *) NULL ;
198 }
199
200 /*-----------------------------------------------------------------*/
201 /* findSymWithBlock - finds a symbol with name in with a block     */
202 /*-----------------------------------------------------------------*/
203 void  *findSymWithBlock ( bucket **stab, symbol *sym, int block)
204 {
205    bucket *bp ;
206
207    bp = stab[hashKey(sym->name)] ;
208    while (bp)
209    {
210       if ( strcmp (bp->name,sym->name) == 0 &&
211            bp->block <= block )
212               break ;
213       bp = bp->next ;
214    }
215
216    return ( bp ? bp->sym : (void *) NULL ) ;
217 }
218
219 /*------------------------------------------------------------------*/
220 /* newSymbol () - returns a new pointer to a symbol                 */
221 /*------------------------------------------------------------------*/
222 symbol *newSymbol (char *name, int scope )
223 {
224    symbol *sym ;
225    
226    ALLOC(sym,sizeof(symbol));   
227
228    strcpy(sym->name,name);             /* copy the name    */
229    sym->level = scope ;                /* set the level    */
230    sym->block = currBlockno ;
231    sym->lineDef = yylineno ;    /* set the line number */   
232    return sym ;
233 }
234
235 /*------------------------------------------------------------------*/
236 /* newLink - creates a new link (declarator,specifier)              */
237 /*------------------------------------------------------------------*/
238 link  *newLink ()
239 {
240    link *p ;
241
242    ALLOC(p,sizeof(link));
243
244    return p;
245 }
246
247 /*------------------------------------------------------------------*/
248 /* newStruct - creats a new structdef from the free list            */
249 /*------------------------------------------------------------------*/
250 structdef   *newStruct  ( char   *tag   )
251 {
252    structdef  *s;
253
254    ALLOC(s,sizeof(structdef));
255    
256    strcpy(s->tag,tag) ;                     /* copy the tag            */
257    return s ;
258 }
259
260 /*------------------------------------------------------------------*/
261 /* pointerTypes - do the computation for the pointer types          */
262 /*------------------------------------------------------------------*/
263 void pointerTypes (link *ptr, link *type)
264 {    
265     if (IS_SPEC(ptr))
266         return ;
267     
268     /* find the first pointer type */
269     while (ptr && !IS_PTR(ptr)) 
270         ptr = ptr->next;
271
272     /* could not find it */
273     if (!ptr || IS_SPEC(ptr) ||
274         DCL_TYPE(ptr) != UPOINTER)
275         return ;
276         
277     /* change the pointer type depending on the 
278        storage class of the type */
279     if (IS_SPEC(type)) {
280         DCL_PTR_CONST(ptr) = SPEC_CONST(type);
281         DCL_PTR_VOLATILE(ptr) = SPEC_VOLATILE(type);
282         switch (SPEC_SCLS(type)) {
283         case S_XDATA:
284             DCL_TYPE(ptr) = FPOINTER;
285             break;
286         case S_IDATA:
287             DCL_TYPE(ptr) = IPOINTER ;
288             break;
289         case S_PDATA:
290             DCL_TYPE(ptr) = PPOINTER ;
291             break;
292         case S_DATA:
293             DCL_TYPE(ptr) = POINTER ;
294             break;
295         case S_CODE:
296             DCL_PTR_CONST(ptr) = port->mem.code_ro;
297             DCL_TYPE(ptr) = CPOINTER ;
298             break;
299         case S_EEPROM:
300             DCL_TYPE(ptr) = EEPPOINTER;
301             break;
302         default:
303             DCL_TYPE(ptr) = GPOINTER;
304             break;
305         }
306         /* the storage class of type ends here */
307         SPEC_SCLS(type) =
308             SPEC_CONST(type) =
309             SPEC_VOLATILE(type) = 0;
310     }    
311     
312     /* now change all the remaining unknown pointers
313        to generic pointers */
314     while (ptr) {
315         if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER)
316             DCL_TYPE(ptr) = GPOINTER;
317         ptr = ptr->next;
318     }
319
320     /* same for the type although it is highly unlikely that
321        type will have a pointer */
322     while (type) {
323         if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER)
324             DCL_TYPE(type) = GPOINTER;
325         type = type->next;
326     }
327
328 }
329
330 /*------------------------------------------------------------------*/
331 /* addDecl - adds a declarator @ the end of a chain                 */
332 /*------------------------------------------------------------------*/
333 void  addDecl ( symbol *sym, int type , link *p )
334 {
335     link    *head;
336     link    *tail;
337     link        *t ;
338     
339     /* if we are passed a link then set head & tail */
340     if ( p )  {
341         tail = head = p ;
342         while ( tail->next )
343             tail = tail->next ;
344     }
345     else {
346         head = tail = newLink() ;
347         DCL_TYPE(head) = type   ;
348     }
349     
350     /* if this is the first entry   */
351     if ( !sym->type )  {
352         sym->type = head ;
353         sym->etype = tail ;
354     }
355     else   {
356         if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) {
357             sym->etype = mergeSpec(sym->etype,head);
358         }
359         else {
360             if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) {
361                 t = sym->type ;
362                 while (t->next != sym->etype) t = t->next ;
363                 t->next = head ;
364                 tail->next = sym->etype;
365             } else {
366                 sym->etype->next = head;
367                 sym->etype   = tail;
368             }
369         }
370     }
371     
372     /* if the type is a unknown pointer and has
373        a tspec then take the storage class const & volatile
374        attribute from the tspec & make it those of this
375        symbol */
376     if (p &&
377         !IS_SPEC(p) && 
378         DCL_TYPE(p) == UPOINTER &&
379         DCL_TSPEC(p)) {
380         if (!IS_SPEC(sym->etype)) {
381             sym->etype = sym->etype->next = newLink();
382             sym->etype->class = SPECIFIER;
383         }
384         SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p));
385         SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p));
386         SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p));
387         DCL_TSPEC(p) = NULL;
388     }
389     return  ;
390 }
391
392 /*------------------------------------------------------------------*/
393 /* mergeSpec - merges two specifiers and returns the new one       */
394 /*------------------------------------------------------------------*/
395 link  *mergeSpec ( link *dest, link *src )
396 {
397     /* if noun different then src overrides */
398     if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest))
399         SPEC_NOUN(dest) = SPEC_NOUN(src) ;
400     
401     if (! SPEC_SCLS(dest))  /* if destination has no storage class */
402         SPEC_SCLS(dest) = SPEC_SCLS(src) ;
403     
404     /* copy all the specifications  */
405     SPEC_LONG(dest) |= SPEC_LONG(src);
406     SPEC_SHORT(dest) |= SPEC_SHORT(src);
407     SPEC_USIGN(dest) |= SPEC_USIGN(src);
408     SPEC_STAT(dest) |= SPEC_STAT(src);
409     SPEC_EXTR(dest) |= SPEC_EXTR(src);
410     SPEC_ABSA(dest) |= SPEC_ABSA(src);
411     SPEC_RENT(dest) |= SPEC_RENT(src);
412     SPEC_INTN(dest) |= SPEC_INTN(src);
413     SPEC_BANK(dest) |= SPEC_BANK(src);
414     SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src);
415     SPEC_CRTCL(dest) |= SPEC_CRTCL(src);
416     SPEC_ADDR(dest) |= SPEC_ADDR(src);
417     SPEC_OCLS(dest)  = SPEC_OCLS(src);
418     SPEC_BLEN(dest) |= SPEC_BLEN(src);
419     SPEC_BSTR(dest) |= SPEC_BSTR(src);
420     SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src);
421     SPEC_NONBANKED(dest) |= SPEC_NONBANKED(src);
422
423     if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL )
424         SPEC_STRUCT(dest) = SPEC_STRUCT(src);   
425     
426     return dest ;
427 }
428
429 /*------------------------------------------------------------------*/
430 /* cloneSpec - copies the entire spec and returns a new spec        */
431 /*------------------------------------------------------------------*/
432 link  *cloneSpec ( link *src )
433 {
434     link  *spec ;
435     
436     /* go thru chain till we find the specifier */
437     while ( src && src->class != SPECIFIER )
438         src = src->next ;
439     
440     spec = newLink() ;
441     memcpy (spec,src,sizeof(link));
442     return spec ;
443 }
444
445 /*------------------------------------------------------------------*/
446 /* genSymName - generates and returns a name used for anonymous vars*/
447 /*------------------------------------------------------------------*/
448 char  *genSymName ( int level )
449 {
450     static   int gCount = 0 ;
451     static   char gname[SDCC_NAME_MAX+1] ;
452     
453     sprintf (gname,"__%04d%04d",level,gCount++);
454     return gname ;
455 }
456
457 /*------------------------------------------------------------------*/
458 /* getSpec - returns the specifier part from a declaration chain    */
459 /*------------------------------------------------------------------*/
460 link  *getSpec ( link *p )
461 {
462     link *loop ;
463     
464     loop = p ;
465     while ( p && ! (IS_SPEC(p)))
466         p = p->next ;
467     
468     return p ;
469 }
470
471 /*------------------------------------------------------------------*/
472 /* newCharLink() - creates an int type                              */
473 /*------------------------------------------------------------------*/
474 link  *newCharLink()
475 {
476     link *p;
477     
478     p = newLink();
479     p->class = SPECIFIER ;
480     SPEC_NOUN(p) = V_CHAR ;
481     
482     return p;
483 }
484
485 /*------------------------------------------------------------------*/
486 /* newFloatLink - a new Float type                                  */
487 /*------------------------------------------------------------------*/
488 link *newFloatLink()
489 {
490     link *p;
491     
492     p = newLink();
493     p->class = SPECIFIER ;
494     SPEC_NOUN(p) = V_FLOAT ;
495     
496     return p;
497 }
498
499 /*------------------------------------------------------------------*/
500 /* newLongLink() - new long type                                    */
501 /*------------------------------------------------------------------*/
502 link *newLongLink()
503 {
504     link *p;
505
506     p = newLink();
507     p->class = SPECIFIER ;
508     SPEC_NOUN(p) = V_INT ;
509     SPEC_LONG(p) = 1;
510     
511     return p;
512 }
513
514 /*------------------------------------------------------------------*/
515 /* newIntLink() - creates an int type                               */
516 /*------------------------------------------------------------------*/
517 link  *newIntLink()
518 {
519     link *p;
520     
521     p = newLink();
522     p->class = SPECIFIER ;
523     SPEC_NOUN(p) = V_INT ;
524     
525     return p;
526 }
527
528 /*------------------------------------------------------------------*/
529 /* getSize - returns size of a type chain in bits                   */
530 /*------------------------------------------------------------------*/
531 unsigned int   getSize ( link *p )
532 {
533     /* if nothing return 0 */
534     if ( ! p )
535         return 0 ;
536     if ( IS_SPEC(p) ) { /* if this is the specifier then */
537         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
538         case V_INT:
539             return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
540         case V_FLOAT:
541             return FLOATSIZE ;
542         case V_CHAR:
543             return CHARSIZE ;
544         case V_VOID:
545             return   0 ;
546         case V_STRUCT:
547             return SPEC_STRUCT(p)->size ;
548         case V_LABEL:
549             return 0 ;
550         case V_SBIT:
551             return BITSIZE ;
552         case V_BIT:
553             return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
554         default  :
555             return 0 ;
556         }
557     }
558     
559     /* this is a specifier  */
560     switch (DCL_TYPE(p))  {
561     case FUNCTION:
562         return 2;
563     case ARRAY:
564         return DCL_ELEM(p) * getSize (p->next) ;
565     case IPOINTER:
566     case PPOINTER:
567     case POINTER:
568         return ( PTRSIZE ) ;
569     case EEPPOINTER:
570     case FPOINTER:
571     case CPOINTER:
572         return ( FPTRSIZE );
573     case GPOINTER:      
574         return ( GPTRSIZE );
575         
576     default     :
577         return  0 ;
578     }
579 }
580
581 /*------------------------------------------------------------------*/
582 /* bitsForType - returns # of bits required to store this type      */
583 /*------------------------------------------------------------------*/
584 unsigned int   bitsForType ( link *p )
585 {
586     /* if nothing return 0 */
587     if ( ! p )
588         return 0 ;
589     
590     if ( IS_SPEC(p) ) { /* if this is the specifier then */
591         
592         switch (SPEC_NOUN(p)) { /* depending on the specifier type */
593         case V_INT:
594             return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
595         case V_FLOAT:
596             return FLOATSIZE*8 ;
597         case V_CHAR:
598             return   CHARSIZE*8 ;
599         case V_VOID:
600             return   0 ;
601         case V_STRUCT:
602             return   SPEC_STRUCT(p)->size*8 ;
603         case V_LABEL:
604             return 0 ;
605         case V_SBIT:
606             return 1 ;
607         case V_BIT:
608             return SPEC_BLEN(p);
609         default  :
610             return 0 ;
611         }
612     }
613     
614     /* this is a specifier  */
615     switch (DCL_TYPE(p))  {
616     case FUNCTION:
617         return 2;
618     case ARRAY:
619         return DCL_ELEM(p) * getSize (p->next) *8 ;
620     case IPOINTER:
621     case PPOINTER:
622     case POINTER:
623         return ( PTRSIZE * 8) ;
624     case EEPPOINTER:
625     case FPOINTER:
626     case CPOINTER:
627         return ( FPTRSIZE * 8);
628     case GPOINTER:
629         return ( GPTRSIZE * 8);
630         
631     default     :
632         return  0 ;
633     }
634 }
635
636 /*------------------------------------------------------------------*/
637 /* copySymbolChain - copies a symbol chain                          */
638 /*------------------------------------------------------------------*/
639 symbol *copySymbolChain (symbol *src)
640 {
641         symbol *dest ;
642
643         if (!src)
644                 return NULL ;
645
646         dest = copySymbol(src);
647         dest->next = copySymbolChain(src->next);
648         return dest ;
649 }
650
651 /*------------------------------------------------------------------*/
652 /* copySymbol - makes a copy of a symbol                            */
653 /*------------------------------------------------------------------*/
654 symbol  *copySymbol     (symbol *src)
655 {
656         symbol *dest;
657
658         if (!src )
659                 return NULL ;
660
661         dest = newSymbol( src->name, src->level );
662         memcpy(dest,src,sizeof(symbol));
663         dest->level = src->level ;
664         dest->block = src->block ;
665         dest->ival = copyIlist(src->ival);
666         dest->type = copyLinkChain(src->type);
667         dest->etype= getSpec(dest->type);
668         dest->next = NULL ;
669         dest->args = copyValueChain (src->args);
670         dest->key = src->key;
671         dest->calleeSave = src->calleeSave;
672         dest->allocreq = src->allocreq;
673         return dest;
674 }
675
676 /*------------------------------------------------------------------*/
677 /* reverseSyms - reverses the links for a symbol chain      */
678 /*------------------------------------------------------------------*/
679 symbol   *reverseSyms ( symbol *sym)
680 {
681    symbol *prev  , *curr, *next ;
682
683    if (!sym)
684       return NULL ;
685
686    prev = sym ;
687    curr = sym->next ;
688
689    while (curr)
690    {
691       next = curr->next ;
692       curr->next = prev   ;
693       prev = curr ;
694       curr = next ;
695    }
696    sym->next = (void *) NULL ;
697    return prev ;
698 }
699
700 /*------------------------------------------------------------------*/
701 /* reverseLink - reverses the links for a type chain        */
702 /*------------------------------------------------------------------*/
703 link     *reverseLink ( link *type)
704 {
705    link *prev  , *curr, *next ;
706
707    if (!type)
708       return NULL ;
709
710    prev = type ;
711    curr = type->next ;
712
713    while (curr)
714    {
715       next = curr->next ;
716       curr->next = prev   ;
717       prev = curr ;
718       curr = next ;
719    }
720    type->next = (void *) NULL ;
721    return prev ;
722 }
723
724 /*------------------------------------------------------------------*/
725 /* addSymChain - adds a symbol chain to the symboltable             */
726 /*------------------------------------------------------------------*/
727 void addSymChain ( symbol *symHead )
728 {
729   symbol *sym  = symHead ;
730   symbol *csym = NULL ;
731
732   for (;sym != NULL ; sym = sym->next ) {
733
734     /* if already exists in the symbol table then check if 
735        the previous was an extern definition if yes then   
736        then check if the type match, if the types match then 
737        delete the current entry and add the new entry      */   
738       if ((csym = findSymWithLevel (SymbolTab,sym)) &&
739         csym->level == sym->level) {
740       
741       /* previous definition extern ? */
742       if ( IS_EXTERN(csym->etype) ) {
743         /* do types match ? */
744         if (checkType ( csym->type,sym->type) != 1)
745           /* no then error */
746           werror (E_DUPLICATE,csym->name);
747
748         /* delete current entry */
749         deleteSym (SymbolTab, csym, csym->name );
750         /* add new entry */
751         addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
752       } else /* not extern */
753           werror(E_DUPLICATE,sym->name) ;
754       continue ;
755     }
756     
757     /* check if previously defined */
758     if (csym  && csym->level == sym->level  ) {
759       /* if the previous one was declared as extern */
760       /* then check the type with the current one         */
761       if ( IS_EXTERN(csym->etype) ) {
762         if ( checkType (csym->type, sym->type ) <= 0 )
763           werror (W_EXTERN_MISMATCH,csym->name);
764       }
765     }
766     
767     addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
768   }
769 }
770
771
772 /*------------------------------------------------------------------*/
773 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
774 /*------------------------------------------------------------------*/
775 int funcInChain (link *lnk)
776 {
777     while (lnk) {
778         if (IS_FUNC(lnk))
779             return 1;
780         lnk = lnk->next;
781     }
782     return 0;
783 }
784
785 /*------------------------------------------------------------------*/
786 /* structElemType - returns the type info of a sturct member        */
787 /*------------------------------------------------------------------*/
788 link *structElemType (link *stype, value *id ,value **argsp)
789 {
790     symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
791     
792     if ( ! fields || ! id)
793         return NULL ;
794        
795     /* look for the id */
796     while (fields) {
797         if (strcmp(fields->rname,id->name) == 0) {
798             if (argsp) {
799                 *argsp = fields->args;
800             }
801             return copyLinkChain (fields->type) ;
802         }
803         fields = fields->next ;
804     }
805     werror(E_NOT_MEMBER,id->name);
806     
807     return NULL ;
808 }
809
810 /*------------------------------------------------------------------*/
811 /* getStructElement - returns element of a tructure definition      */
812 /*------------------------------------------------------------------*/
813 symbol *getStructElement ( structdef *sdef, symbol *sym)
814 {
815     symbol *field ;
816     
817     for ( field = sdef->fields ; field ; field = field->next )
818         if ( strcmp(field->name,sym->name) == 0)
819             return field ;
820     
821     werror(E_NOT_MEMBER,sym->name);
822     
823     return sdef->fields ;
824 }
825
826 /*------------------------------------------------------------------*/
827 /* compStructSize - computes the size of a structure                */
828 /*------------------------------------------------------------------*/
829 int   compStructSize (int su, structdef  *sdef )
830 {
831     int sum = 0 , usum =0;
832     int bitOffset = 0 ;
833     symbol   *loop ;
834     
835     /* for the identifiers  */
836     loop = sdef->fields ;
837     while ( loop ) {
838
839         /* create the internal name for this variable */
840         sprintf (loop->rname,"_%s",loop->name);
841         loop->offset = ( su == UNION ? sum = 0 : sum ) ;
842         SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
843
844         /* if this is a bit field  */
845         if (loop->bitVar)       {
846             
847             /* change it to a unsigned bit */
848             SPEC_NOUN(loop->etype) = V_BIT ;
849             SPEC_USIGN(loop->etype) = 1     ;
850             /* check if this fit into the remaining   */
851             /* bits of this byte else align it to the */
852             /* next byte boundary                     */
853             if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset))  {
854                 SPEC_BSTR(loop->etype) = bitOffset   ;
855                 sum += (loop->bitVar / 8)  ;
856                 bitOffset += (loop->bitVar % 8);
857             } 
858             else  /* does not fit */
859                 {
860                     bitOffset = 0 ;
861                     loop->offset++;   /* go to the next byte  */
862                     sum++         ;
863                     SPEC_BSTR(loop->etype) = bitOffset   ;
864                     sum += (loop->bitVar / 8)  ;
865                     bitOffset += (loop->bitVar % 8);
866                 }
867             /* if this is the last field then pad */
868             if (!loop->next && bitOffset) {
869                 bitOffset = 0 ;
870                 sum++ ;
871             }
872         }
873         else {
874             checkDecl (loop);
875             sum += getSize (loop->type) ;
876         }
877
878         /* if function then do the arguments for it */
879         if (funcInChain(loop->type)) {
880             processFuncArgs (loop, 1);
881         }
882
883         loop = loop->next ;
884
885         /* if this is not a bitfield but the */
886         /* previous one was and did not take */
887         /* the whole byte then pad the rest  */
888         if ((loop && !loop->bitVar) && bitOffset) {
889             bitOffset = 0 ;
890             sum++ ;
891         }
892         
893         /* if union then size = sizeof larget field */
894         if (su == UNION)
895             usum = max(usum,sum);
896     
897     }
898     
899     return (su == UNION ? usum : sum);
900 }
901
902 /*------------------------------------------------------------------*/
903 /* checkSClass - check the storage class specification              */
904 /*------------------------------------------------------------------*/
905 static void  checkSClass ( symbol *sym )
906 {         
907     /* type is literal can happen foe enums change
908        to auto */
909     if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
910         SPEC_SCLS(sym->etype) = S_AUTO;
911
912     /* if sfr or sbit then must also be */
913     /* volatile the initial value will be xlated */
914     /* to an absolute address */
915     if (SPEC_SCLS(sym->etype) == S_SBIT ||
916         SPEC_SCLS(sym->etype) == S_SFR ) {
917         SPEC_VOLATILE(sym->etype) = 1;
918         /* if initial value given */
919         if (sym->ival) {
920             SPEC_ABSA(sym->etype) = 1;
921             SPEC_ADDR(sym->etype) =
922                 (int) list2int(sym->ival);
923             sym->ival = NULL;
924         }
925     }
926
927     /* if absolute address given then it mark it as
928        volatile */
929     if (IS_ABSOLUTE(sym->etype))
930         SPEC_VOLATILE(sym->etype) = 1;
931
932     /* global variables declared const put into code */
933     if (sym->level == 0 && 
934         SPEC_SCLS(sym->etype) == S_CONSTANT) {
935         SPEC_SCLS(sym->etype) = S_CODE ;
936         SPEC_CONST(sym->etype) = 1;
937     }
938
939     /* global variable in code space is a constant */
940     if (sym->level == 0 && 
941         SPEC_SCLS(sym->etype) == S_CODE &&
942         port->mem.code_ro )
943         SPEC_CONST(sym->etype) = 1;
944     
945
946     /* if bit variable then no storage class can be */
947     /* specified since bit is already a storage */
948     if ( IS_BITVAR(sym->etype)              && 
949          ( SPEC_SCLS(sym->etype) != S_FIXED &&   
950            SPEC_SCLS(sym->etype) != S_SBIT  &&
951            SPEC_SCLS(sym->etype) != S_BIT )
952          ) {
953         werror (E_BITVAR_STORAGE,sym->name);
954         SPEC_SCLS(sym->etype) = S_FIXED ;
955     }
956     
957     /* extern variables cannot be initialized */
958     if (IS_EXTERN(sym->etype) && sym->ival)     {
959         werror(E_EXTERN_INIT,sym->name);
960         sym->ival = NULL;
961     }    
962     
963     /* if this is an automatic symbol then */
964     /* storage class will be ignored and   */
965     /* symbol will be allocated on stack/  */
966     /* data depending on flag             */
967     if ( sym->level                             &&
968          (options.stackAuto || reentrant )      &&
969          ( SPEC_SCLS(sym->etype) != S_AUTO      &&
970            SPEC_SCLS(sym->etype) != S_FIXED     &&
971            SPEC_SCLS(sym->etype) != S_REGISTER  &&
972            SPEC_SCLS(sym->etype) != S_STACK     &&
973            SPEC_SCLS(sym->etype) != S_XSTACK    &&
974            SPEC_SCLS(sym->etype) != S_CONSTANT  )) {
975
976         werror(E_AUTO_ASSUMED,sym->name) ;
977         SPEC_SCLS(sym->etype) = S_AUTO   ;
978     }
979         
980     /* automatic symbols cannot be given   */
981     /* an absolute address ignore it      */
982     if ( sym->level  && 
983          SPEC_ABSA(sym->etype) &&
984          (options.stackAuto || reentrant) )  {
985         werror(E_AUTO_ABSA,sym->name);
986         SPEC_ABSA(sym->etype) = 0 ;
987     }
988         
989     /* arrays & pointers cannot be defined for bits   */
990     /* SBITS or SFRs or BIT                           */
991     if ((IS_ARRAY(sym->type) || IS_PTR(sym->type))  &&
992         ( SPEC_NOUN(sym->etype) == V_BIT          || 
993          SPEC_NOUN(sym->etype) == V_SBIT             ||
994          SPEC_SCLS(sym->etype) == S_SFR              ))
995         werror(E_BIT_ARRAY,sym->name);
996     
997     /* if this is a bit|sbit then set length & start  */
998     if (SPEC_NOUN(sym->etype) == V_BIT              ||
999         SPEC_NOUN(sym->etype) == V_SBIT             )  {
1000         SPEC_BLEN(sym->etype) = 1 ;
1001         SPEC_BSTR(sym->etype) = 0 ;
1002     }    
1003     
1004     /* variables declared in CODE space must have */
1005     /* initializers if not an extern */
1006     if (SPEC_SCLS(sym->etype) == S_CODE && 
1007         sym->ival == NULL               &&
1008         !sym->level                     &&
1009         port->mem.code_ro               &&
1010         !IS_EXTERN(sym->etype)) 
1011         werror(E_CODE_NO_INIT,sym->name);
1012     
1013     /* if parameter or local variable then change */
1014     /* the storage class to reflect where the var will go */
1015     if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1016         if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1017         {
1018             SPEC_SCLS(sym->etype) = (options.useXstack  ?
1019                                      S_XSTACK : S_STACK ) ;
1020         }
1021         else
1022         {
1023             /* hack-o-matic! I see no reason why the useXstack option should ever
1024              * control this allcoation, but the code was originally that way, and
1025              * changing it for non-390 ports breaks the compiler badly.
1026              */
1027             bool useXdata = IS_DS390_PORT ? options.model : options.useXstack;
1028             SPEC_SCLS(sym->etype) = (useXdata  ?
1029                                      S_XDATA : S_FIXED ) ;
1030         }
1031     }
1032 }
1033
1034 /*------------------------------------------------------------------*/
1035 /* changePointer - change pointer to functions                      */
1036 /*------------------------------------------------------------------*/
1037 void  changePointer  (symbol  *sym)
1038 {
1039     link *p ;
1040     
1041     /* go thru the chain of declarations   */
1042     /* if we find a pointer to a function  */
1043     /* unconditionally change it to a ptr  */
1044     /* to code area                        */
1045     for ( p = sym->type ; p ; p = p->next) {
1046         if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1047             DCL_TYPE(p) = GPOINTER ;
1048         if ( IS_PTR(p) && IS_FUNC(p->next))
1049             DCL_TYPE(p) = CPOINTER ;
1050     }
1051 }
1052
1053 /*------------------------------------------------------------------*/
1054 /* checkDecl - does semantic validation of a declaration                   */
1055 /*------------------------------------------------------------------*/
1056 int checkDecl ( symbol *sym )
1057 {
1058     
1059     checkSClass  (sym); /* check the storage class      */
1060     changePointer(sym);  /* change pointers if required */
1061
1062     /* if this is an array without any dimension
1063        then update the dimension from the initial value */
1064     if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1065         DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);    
1066
1067     return 0 ;
1068 }
1069
1070 /*------------------------------------------------------------------*/
1071 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1072 /*------------------------------------------------------------------*/
1073 link  *copyLinkChain ( link *p)
1074 {
1075     link  *head, *curr , *loop;
1076     
1077     curr = p ;
1078     head = loop = ( curr ? newLink() : (void *) NULL) ;
1079     while (curr)   {
1080         memcpy(loop,curr,sizeof(link)) ; /* copy it */
1081         loop->next = (curr->next ? newLink() : (void *) NULL) ;
1082         loop = loop->next ;
1083         curr = curr->next ;
1084     }
1085     
1086     return head ;
1087 }
1088
1089
1090 /*------------------------------------------------------------------*/
1091 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1092 /*                symbols in the given block                        */
1093 /*------------------------------------------------------------------*/
1094 void cleanUpBlock ( bucket **table, int block)
1095 {    
1096     int i ;
1097     bucket  *chain;
1098     
1099     /* go thru the entire  table  */
1100     for ( i = 0 ; i < 256; i++ ) {
1101         for ( chain = table[i]; chain ; chain = chain->next ) {
1102             if (chain->block >= block) {
1103                 deleteSym (table,chain->sym,chain->name);                                 
1104             }   
1105         }
1106     }
1107 }
1108
1109 /*------------------------------------------------------------------*/
1110 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1111 /*                symbols in the given level                        */
1112 /*------------------------------------------------------------------*/
1113 void  cleanUpLevel   (bucket  **table, int level )
1114 {
1115     int i ;
1116     bucket  *chain;
1117     
1118     /* go thru the entire  table  */
1119     for ( i = 0 ; i < 256; i++ ) {
1120         for ( chain = table[i]; chain ; chain = chain->next ) {
1121             if (chain->level >= level) {
1122                 deleteSym (table,chain->sym,chain->name);                                 
1123             }   
1124         }
1125     }
1126 }
1127
1128 /*------------------------------------------------------------------*/
1129 /* computeType - computes the resultant type from two types         */
1130 /*------------------------------------------------------------------*/
1131 link *computeType ( link *type1, link *type2)
1132 {
1133     link *rType ;
1134     link *reType;
1135     link *etype1 = getSpec(type1);
1136     link *etype2 = getSpec(type2);
1137     
1138     /* if one of them is a float then result is a float */
1139     /* here we assume that the types passed are okay */
1140     /* and can be cast to one another                */
1141     /* which ever is greater in size */
1142     if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1143         rType = newFloatLink();
1144     else
1145         /* if only one of them is a bit variable
1146            then the other one prevails */
1147         if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1148             rType = copyLinkChain(type2);
1149         else
1150             if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1151                 rType = copyLinkChain(type1);
1152             else
1153                 /* if one of them is a pointer then that
1154                    prevails */
1155                 if (IS_PTR(type1))
1156                     rType = copyLinkChain(type1);
1157                 else
1158                     if (IS_PTR(type2))
1159                         rType = copyLinkChain(type2);
1160                     else
1161                         if (getSize (type1) > getSize(type2) )
1162                             rType = copyLinkChain(type1);
1163                         else
1164                             rType = copyLinkChain(type2);
1165     
1166     reType = getSpec(rType);
1167     
1168     /* if either of them unsigned then make this unsigned */
1169     if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1170         SPEC_USIGN(reType) = 1;
1171     
1172     /* if result is a literal then make not so */
1173     if (IS_LITERAL(reType))
1174         SPEC_SCLS(reType) = S_REGISTER ;
1175     
1176     return rType;
1177 }
1178
1179 /*------------------------------------------------------------------*/
1180 /* checkType - will do type check return 1 if match                 */
1181 /*------------------------------------------------------------------*/
1182 int checkType ( link *dest, link *src )
1183 {
1184     if ( !dest && !src)
1185         return 1;
1186     
1187     if (dest && !src)
1188         return 0;
1189     
1190     if (src && !dest)
1191         return 0;
1192     
1193     /* if dest is a declarator then */
1194     if (IS_DECL(dest)) {
1195         if (IS_DECL(src)) {
1196             if (DCL_TYPE(src) == DCL_TYPE(dest))
1197                 return checkType(dest->next,src->next);
1198             else
1199                 if (IS_PTR(src) && IS_PTR(dest))
1200                     return -1;
1201                 else
1202                     if (IS_PTR(dest) && IS_ARRAY(src))
1203                         return -1;
1204                     else 
1205                         if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1206                             return -1 * checkType (dest->next,src) ;
1207                         else
1208                             return 0;
1209         }
1210         else
1211             if (IS_PTR(dest) && IS_INTEGRAL(src))
1212                 return -1;
1213             else
1214                 return 0;
1215     }
1216     
1217     /* if one of them is a void then ok */
1218     if (SPEC_NOUN(dest) == V_VOID    &&
1219         SPEC_NOUN(src)  != V_VOID    )
1220         return -1 ;
1221     
1222     if (SPEC_NOUN(dest) != V_VOID &&
1223         SPEC_NOUN(src) == V_VOID )
1224         return -1;
1225     
1226     /* char === to short */
1227     if (SPEC_NOUN(dest) == V_CHAR &&
1228         SPEC_NOUN(src)  == V_INT  &&
1229         SPEC_SHORT(src)           )
1230         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1231
1232     if (SPEC_NOUN(src) == V_CHAR &&
1233         SPEC_NOUN(dest)  == V_INT  &&
1234         SPEC_SHORT(dest)           )
1235         return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);    
1236
1237     /* if they are both bitfields then if the lengths
1238        and starts don't match */
1239     if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1240         (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1241          SPEC_BSTR(dest) != SPEC_BSTR(src)))
1242         return -1;
1243
1244     /* it is a specifier */
1245     if (SPEC_NOUN(dest) != SPEC_NOUN(src))      {
1246         if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1247             IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1248             getSize(dest) == getSize(src))
1249             return 1;
1250         else
1251             if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1252                 return -1;
1253         else
1254             return 0;
1255     }
1256     else
1257         if (IS_STRUCT(dest)) {
1258             if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1259                 return 0 ;
1260             else 
1261                 return 1 ;
1262         }
1263     if (SPEC_LONG(dest) != SPEC_LONG(src))
1264         return -1;
1265     
1266     if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1267         return -1;
1268     
1269     if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1270         return -2;
1271     
1272     return 1;   
1273 }
1274
1275 /*------------------------------------------------------------------*/
1276 /* inCalleeSaveList - return 1 if found in calle save list          */
1277 /*------------------------------------------------------------------*/
1278 bool inCalleeSaveList ( char *s)
1279 {
1280     int i;
1281     
1282     for (i = 0 ; options.calleeSaves[i] ; i++ )
1283         if (strcmp(options.calleeSaves[i],s) == 0)
1284             return 1;
1285
1286     return 0;
1287 }
1288
1289 /*------------------------------------------------------------------*/
1290 /* checkFunction - does all kinds of check on a function            */
1291 /*------------------------------------------------------------------*/
1292 int   checkFunction (symbol   *sym)
1293 {
1294     symbol *csym ;
1295     value  *exargs, *acargs ;
1296     int argCnt = 0 ;
1297     
1298     /* if not type then some kind of error */
1299     if ( !sym->type )
1300         return 0;
1301     
1302     /* if the function has no type then make it return int */
1303     if ( !sym->type->next )
1304         sym->type->next = sym->etype = newIntLink();
1305    
1306     /* function cannot return aggregate */
1307     if (IS_AGGREGATE(sym->type->next))   {
1308         werror(E_FUNC_AGGR,sym->name);
1309         return 0;      
1310     }
1311            
1312     /* function cannot return bit */
1313     if (IS_BITVAR(sym->type->next)) {
1314         werror(E_FUNC_BIT,sym->name);
1315         return 0;
1316     }
1317     
1318     /* check if this function is defined as calleeSaves
1319        then mark it as such */
1320     sym->calleeSave = inCalleeSaveList(sym->name); 
1321
1322     /* if interrupt service routine  */
1323     /* then it cannot have arguments */
1324     if ( sym->args  && IS_ISR(sym->etype) && !IS_VOID(sym->args->type))   {
1325         werror(E_INT_ARGS,sym->name);     
1326         sym->args = NULL ;
1327     }
1328     
1329     if (!(csym = findSym (SymbolTab, sym, sym->name )))
1330         return 1 ;  /* not defined nothing more to check  */
1331     
1332     /* check if body already present */
1333     if ( csym && csym->fbody )   {
1334         werror(E_FUNC_BODY,sym->name);
1335         return 0;
1336     }
1337     
1338     /* check the return value type   */
1339     if (checkType (csym->type,sym->type) <= 0) {
1340         werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1341         werror (E_CONTINUE,"previous defintion type ");
1342         printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1343         werror (E_CONTINUE,"current definition type ");
1344         printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1345         return 0;
1346     }
1347
1348     if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1349         werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1350         return 0;
1351     }
1352
1353     if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1354         werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1355         return 0;
1356     }
1357
1358     /* compare expected agrs with actual args */
1359     exargs = csym->args ;
1360     acargs = sym->args  ;
1361     
1362     /* for all the expected args do */
1363     for (argCnt =  1    ; 
1364          exargs && acargs ; 
1365          exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1366         if ( checkType(exargs->type,acargs->type) <= 0) {
1367             werror(E_ARG_TYPE,argCnt);
1368             return 0;
1369         }
1370     }
1371     
1372     /* if one them ended we have a problem */
1373     if ((exargs && !acargs && !IS_VOID(exargs->type)) || 
1374         (!exargs && acargs && !IS_VOID(acargs->type)))
1375         werror(E_ARG_COUNT);
1376     
1377     /* replace with this defition */
1378     sym->cdef = csym->cdef;
1379     deleteSym (SymbolTab,csym,csym->name);
1380     addSym    (SymbolTab,sym,sym->name,sym->level,sym->block);
1381     if (IS_EXTERN(csym->etype) && !
1382         IS_EXTERN(sym->etype)) {
1383         addSet(&publics,sym);
1384     }
1385     return 1 ;      
1386 }
1387
1388 /*-----------------------------------------------------------------*/
1389 /* processFuncArgs - does some processing with function args       */
1390 /*-----------------------------------------------------------------*/
1391 void  processFuncArgs   (symbol *func, int ignoreName)
1392 {
1393     value *val ;
1394     int pNum = 1;   
1395     
1396
1397     /* if this function has variable argument list */
1398     /* then make the function a reentrant one      */
1399     if (func->hasVargs)
1400         SPEC_RENT(func->etype) = 1;
1401
1402     /* check if this function is defined as calleeSaves
1403        then mark it as such */
1404     func->calleeSave = inCalleeSaveList(func->name); 
1405
1406     val = func->args; /* loop thru all the arguments   */
1407         
1408     /* if it is void then remove parameters */
1409     if (val && IS_VOID(val->type)) {     
1410         func->args = NULL ;
1411         return ;
1412     }
1413
1414     /* reset regparm for the port */
1415     (*port->reset_regparms)();
1416     /* if any of the arguments is an aggregate */
1417     /* change it to pointer to the same type */
1418     while (val) {
1419         /* mark it as a register parameter if
1420            the function does not have VA_ARG
1421            and as port dictates
1422            not inhibited by command line option or #pragma */
1423         if (!func->hasVargs       &&        
1424             !options.noregparms   &&
1425             !IS_RENT(func->etype) &&
1426             (*port->reg_parm)(val->type)) {
1427             SPEC_REGPARM(val->etype) = 1;
1428         }
1429         
1430         if ( IS_AGGREGATE(val->type)) {
1431             /* if this is a structure */
1432             /* then we need to add a new link */
1433             if (IS_STRUCT(val->type)) {
1434                                 /* first lets add DECLARATOR type */
1435                 link *p = val->type ;
1436                 
1437                 werror(W_STRUCT_AS_ARG,val->name);
1438                 val->type = newLink();
1439                 val->type->next = p ;                           
1440             }
1441             
1442             /* change to a pointer depending on the */
1443             /* storage class specified                          */
1444             switch (SPEC_SCLS(val->etype)) {
1445             case S_IDATA:
1446                 DCL_TYPE(val->type) = IPOINTER;
1447                 break;
1448             case S_PDATA:
1449                 DCL_TYPE(val->type) = PPOINTER;
1450                 break;
1451             case S_FIXED:
1452             case S_AUTO:
1453             case S_DATA:
1454             case S_REGISTER:
1455                 DCL_TYPE(val->type) = POINTER ;
1456                 break;
1457             case S_CODE:
1458                 DCL_TYPE(val->type) = CPOINTER;
1459                 break;
1460             case S_XDATA:
1461                 DCL_TYPE(val->type) = FPOINTER;
1462                 break;
1463             case S_EEPROM:
1464                 DCL_TYPE(val->type) = EEPPOINTER;
1465                 break;
1466             default :
1467                 DCL_TYPE(val->type) = GPOINTER;
1468             }
1469             
1470             /* is there is a symbol associated then */
1471             /* change the type of the symbol as well*/
1472             if ( val->sym ) {          
1473                 val->sym->type = copyLinkChain(val->type);
1474                 val->sym->etype = getSpec(val->sym->type);
1475             }
1476         }
1477         
1478         val = val->next ;
1479         pNum++;
1480     }
1481     
1482     /* if this function is reentrant or */
1483     /* automatics r 2b stacked then nothing */
1484     if (IS_RENT(func->etype) || options.stackAuto )
1485         return ;
1486     
1487     val = func->args;
1488     pNum = 1;
1489     while (val) {
1490         
1491         /* if a symbolname is not given  */
1492         /* synthesize a variable name */
1493         if (!val->sym) {
1494
1495             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1496             val->sym = newSymbol(val->name,1);
1497             SPEC_OCLS(val->etype) = port->mem.default_local_map;
1498             val->sym->type = copyLinkChain (val->type);
1499             val->sym->etype = getSpec (val->sym->type);
1500             val->sym->_isparm = 1;
1501             strcpy (val->sym->rname,val->name);  
1502             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1503                 SPEC_STAT(func->etype);
1504             addSymChain(val->sym);
1505    
1506         }
1507         else  /* symbol name given create synth name */      {
1508             
1509             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1510             strcpy (val->sym->rname,val->name);
1511             val->sym->_isparm = 1;
1512             SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) = 
1513                 (options.model ? xdata : data);
1514             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) = 
1515                 SPEC_STAT(func->etype);
1516         }
1517         val = val->next ;
1518     }
1519 }
1520
1521 /*-----------------------------------------------------------------*/
1522 /* isSymbolEqual - compares two symbols return 1 if they match     */
1523 /*-----------------------------------------------------------------*/
1524 int isSymbolEqual (symbol *dest, symbol *src)
1525 {
1526     /* if pointers match then equal */
1527     if (dest == src)
1528         return 1;
1529
1530     /* if one of them is null then don't match */
1531     if (!dest || !src)
1532         return 0;
1533     
1534     /* if both of them have rname match on rname */
1535     if (dest->rname[0] && src->rname[0]) 
1536         return (!strcmp(dest->rname,src->rname));
1537     
1538     /* otherwise match on name */
1539     return (!strcmp(dest->name,src->name));
1540 }
1541
1542 /*-----------------------------------------------------------------*/ 
1543 /* printTypeChain - prints the type chain in human readable form   */
1544 /*-----------------------------------------------------------------*/ 
1545 void printTypeChain (link *type, FILE *of)
1546 {
1547     int nlr = 0;
1548
1549     if (!of) {
1550         of = stdout;
1551         nlr = 1;
1552     }
1553
1554     while (type) {
1555         if (IS_DECL(type)) {
1556             switch (DCL_TYPE(type)) {
1557             case FUNCTION:
1558                 fprintf (of,"function ");
1559                 break;
1560             case GPOINTER:
1561                 fprintf (of,"_generic * ");
1562                 if (DCL_PTR_CONST(type))
1563                     fprintf(of,"const ");
1564                 break;          
1565             case CPOINTER:
1566                 fprintf (of,"_code * ");
1567                 if (DCL_PTR_CONST(type))
1568                     fprintf(of,"const ");
1569                 break;
1570             case FPOINTER:
1571                 fprintf (of,"_far * ");
1572                 if (DCL_PTR_CONST(type))
1573                     fprintf(of,"const ");
1574                 break;
1575             case EEPPOINTER:
1576                 fprintf (of,"_eeprom * ");
1577                 if (DCL_PTR_CONST(type))
1578                     fprintf(of,"const ");
1579                 break;
1580                 
1581             case POINTER:
1582                 fprintf (of,"_near * ");
1583                 if (DCL_PTR_CONST(type))
1584                     fprintf(of,"const ");       
1585                 break;
1586             case IPOINTER:
1587                 fprintf (of,"_idata *");
1588                 if (DCL_PTR_CONST(type))
1589                     fprintf(of,"const ");       
1590                 break; 
1591             case PPOINTER:
1592                 fprintf (of,"_pdata *");
1593                 if (DCL_PTR_CONST(type))
1594                     fprintf(of,"const ");       
1595                 break;
1596             case UPOINTER:
1597                 fprintf (of," _unkown *");
1598                 if (DCL_PTR_CONST(type))
1599                     fprintf(of,"const ");       
1600                 break;
1601                 
1602             case ARRAY :
1603                 fprintf (of,"array of ");
1604                 break;
1605             }
1606         } else { 
1607             if (SPEC_VOLATILE(type))
1608                 fprintf (of,"volatile "); 
1609             if (SPEC_USIGN(type))
1610                 fprintf (of,"unsigned ");
1611             
1612             switch (SPEC_NOUN(type)) {
1613             case V_INT:
1614                 if (IS_LONG(type))
1615                     fprintf (of,"long ");
1616                 else
1617                     if (IS_SHORT(type))
1618                         fprintf (of,"short ");
1619                     else
1620                         fprintf (of,"int ");
1621                 break;
1622
1623             case V_CHAR:
1624                 fprintf(of,"char ");
1625                 break;
1626
1627             case V_VOID:
1628                 fprintf(of,"void ");
1629                 break;
1630
1631             case V_FLOAT:
1632                 fprintf(of,"float ");
1633                 break;
1634
1635             case V_STRUCT:
1636                 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1637                 break;
1638                                   
1639             case V_SBIT:
1640                 fprintf(of,"sbit ");
1641                 break;
1642
1643             case V_BIT:
1644                 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1645                 break;
1646                 
1647             default:
1648                 break;
1649             }
1650         }
1651         type = type->next;
1652     }
1653     if (nlr)
1654         fprintf(of,"\n");
1655 }
1656
1657 /*-----------------------------------------------------------------*/ 
1658 /* cdbTypeInfo - print the type information for debugger           */
1659 /*-----------------------------------------------------------------*/
1660 void cdbTypeInfo (link *type,FILE *of)
1661 {
1662     fprintf(of,"{%d}",getSize(type));
1663     while (type) {
1664         if (IS_DECL(type)) {
1665             switch (DCL_TYPE(type)) {
1666             case FUNCTION:
1667                 fprintf (of,"DF,");
1668                 break;
1669             case GPOINTER:
1670                 fprintf (of,"DG,");             
1671                 break;          
1672             case CPOINTER:
1673                 fprintf (of,"DC,");             
1674                 break;
1675             case FPOINTER:
1676                 fprintf (of,"DX,");             
1677                 break;
1678             case POINTER:
1679                 fprintf (of,"DD,");             
1680                 break;
1681             case IPOINTER:
1682                 fprintf (of,"DI,");
1683                 break;
1684             case PPOINTER:
1685                 fprintf (of,"DP,");
1686                 break;
1687             case EEPPOINTER:
1688                 fprintf (of,"DA,");
1689                 break;
1690             case ARRAY :
1691                 fprintf (of,"DA%d,",DCL_ELEM(type));
1692                 break;
1693             default:
1694                 break;
1695             }
1696         } else { 
1697             switch (SPEC_NOUN(type)) {
1698             case V_INT:
1699                 if (IS_LONG(type))
1700                     fprintf (of,"SL");
1701                 else
1702                     if (IS_SHORT(type))
1703                         fprintf (of,"SS");
1704                     else
1705                         fprintf (of,"SI");
1706                 break;
1707
1708             case V_CHAR:
1709                 fprintf(of,"SC");
1710                 break;
1711
1712             case V_VOID:
1713                 fprintf(of,"SV");
1714                 break;
1715
1716             case V_FLOAT:
1717                 fprintf(of,"SF");
1718                 break;
1719
1720             case V_STRUCT:
1721                 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1722                 break;
1723                                   
1724             case V_SBIT:
1725                 fprintf(of,"SX");
1726                 break;
1727
1728             case V_BIT:
1729                 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1730                 break;
1731
1732             default:
1733                 break;
1734             }
1735             fputs(":",of);
1736             if (SPEC_USIGN(type))
1737                 fputs("U",of);
1738             else
1739                 fputs("S",of);
1740         }
1741         type = type->next;
1742     }
1743 }
1744 /*-----------------------------------------------------------------*/ 
1745 /* cdbSymbol - prints a symbol & its type information for debugger */
1746 /*-----------------------------------------------------------------*/ 
1747 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1748 {
1749     memmap *map;
1750
1751     if (!sym)
1752         return ;
1753     if (!of)
1754         of = stdout;
1755     
1756     if (isFunc)
1757         fprintf(of,"F:");
1758     else
1759         fprintf(of,"S:"); /* symbol record */
1760     /* if this is not a structure symbol then
1761        we need to figure out the scope information */
1762     if (!isStructSym) {
1763         if (!sym->level) {
1764             /* global */
1765             if (IS_STATIC(sym->etype))
1766                 fprintf(of,"F%s$",moduleName); /* scope is file */
1767             else
1768                 fprintf(of,"G$"); /* scope is global */
1769         }
1770         else 
1771             /* symbol is local */
1772             fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1773     } else
1774         fprintf(of,"S$"); /* scope is structure */
1775     
1776     /* print the name, & mangled name */
1777     fprintf(of,"%s$%d$%d(",sym->name,
1778             sym->level,sym->block);
1779
1780     cdbTypeInfo(sym->type,of);
1781     fprintf(of,"),");
1782     
1783     /* print the address space */
1784     map = SPEC_OCLS(sym->etype);
1785     fprintf(of,"%c,%d,%d",
1786             (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1787     
1788     /* if assigned to registers then output register names */   
1789     /* if this is a function then print
1790        if is it an interrupt routine & interrupt number
1791        and the register bank it is using */
1792     if (isFunc)
1793         fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1794                 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1795     /* alternate location to find this symbol @ : eg registers
1796        or spillication */
1797    
1798     if (!isStructSym)
1799         fprintf(of,"\n");
1800 }                   
1801
1802 /*-----------------------------------------------------------------*/ 
1803 /* cdbStruct - print a structure for debugger                      */
1804 /*-----------------------------------------------------------------*/
1805 void cdbStruct ( structdef *sdef,int block,FILE *of,
1806                  int inStruct, char *tag)
1807 {
1808     symbol *sym;
1809
1810     fprintf(of,"T:");
1811     /* if block # then must have function scope */
1812     fprintf(of,"F%s$",moduleName);
1813     fprintf(of,"%s[",(tag ? tag : sdef->tag));
1814     for (sym=sdef->fields ; sym ; sym = sym->next) {
1815         fprintf(of,"({%d}",sym->offset);
1816             cdbSymbol(sym,of,TRUE,FALSE);
1817         fprintf(of,")");
1818     }
1819     fprintf(of,"]");
1820     if (!inStruct)
1821         fprintf(of,"\n");
1822 }
1823
1824 /*------------------------------------------------------------------*/
1825 /* cdbStructBlock - calls struct printing for a blcks               */
1826 /*------------------------------------------------------------------*/
1827 void cdbStructBlock (int block , FILE *of)
1828 {    
1829     int i ;
1830     bucket **table = StructTab;
1831     bucket  *chain;
1832     wassert(of);
1833
1834     /* go thru the entire  table  */
1835     for ( i = 0 ; i < 256; i++ ) {
1836         for ( chain = table[i]; chain ; chain = chain->next ) {
1837             if (chain->block >= block) {
1838                 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1839             }   
1840         }
1841     }
1842 }
1843                 
1844 /*-----------------------------------------------------------------*/ 
1845 /* powof2 - returns power of two for the number if number is pow 2 */
1846 /*-----------------------------------------------------------------*/ 
1847 int powof2 (unsigned long num)
1848 {
1849     int nshifts = 0;
1850     int n1s = 0 ;
1851     
1852     while (num) {
1853         if (num & 1) n1s++ ;
1854         num >>= 1 ;
1855         nshifts++ ;
1856     }
1857     
1858     if (n1s > 1 || nshifts == 0) return 0;
1859     return nshifts - 1 ;
1860 }
1861
1862 symbol *__fsadd ;
1863 symbol *__fssub ;
1864 symbol *__fsmul ;
1865 symbol *__fsdiv ;
1866 symbol *__fseq  ;
1867 symbol *__fsneq ;
1868 symbol *__fslt  ;
1869 symbol *__fslteq;
1870 symbol *__fsgt  ;
1871 symbol *__fsgteq;
1872
1873 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1874 symbol *__muldiv[3][3][2];
1875 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1876 link *__multypes[3][2];
1877 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1878 symbol *__conv[2][3][2];
1879
1880 link *floatType;
1881
1882 static void _makeRegParam(symbol *sym)
1883 {
1884     value *val ;
1885
1886     val = sym->args; /* loop thru all the arguments   */
1887
1888     /* reset regparm for the port */
1889     (*port->reset_regparms)();
1890     while (val) {
1891         SPEC_REGPARM(val->etype) = 1;
1892         sym->argStack -= getSize(val->type);
1893         val = val->next ;
1894     }
1895 }
1896
1897 /*-----------------------------------------------------------------*/ 
1898 /* initCSupport - create functions for C support routines          */
1899 /*-----------------------------------------------------------------*/ 
1900 void initCSupport ()
1901 {
1902     const char *smuldivmod[] = {
1903         "mul", "div", "mod"
1904     };
1905     const char *sbwd[] = {
1906         "char", "int", "long"
1907     };
1908     const char *ssu[] = {
1909         "s", "u"
1910     };
1911         
1912     int bwd, su, muldivmod, tofrom;
1913
1914     floatType= newFloatLink();
1915
1916     for (bwd = 0; bwd < 3; bwd++) {
1917         link *l;
1918         switch (bwd) {
1919         case 0:
1920             l = newCharLink();
1921             break;
1922         case 1:
1923             l = newIntLink();
1924             break;
1925         case 2:
1926             l = newLongLink();
1927             break;
1928         default:
1929             assert(0);
1930         }
1931         __multypes[bwd][0] = l;
1932         __multypes[bwd][1] = copyLinkChain(l);
1933         SPEC_USIGN(__multypes[bwd][1]) = 1;
1934     }
1935
1936     __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1937     __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1938     __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1939     __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1940     __fseq  = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1941     __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1942     __fslt  = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1943     __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1944     __fsgt  = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1945     __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1946
1947     for (tofrom = 0; tofrom < 2; tofrom++) {
1948         for (bwd = 0; bwd < 3; bwd++) {
1949             for (su = 0; su < 2; su++) {
1950                 if (tofrom) {
1951                     sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1952                     __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1953                 }
1954                 else {
1955                     sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1956                     __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
1957                 }
1958             }
1959         }
1960     }
1961
1962     for (muldivmod = 0; muldivmod < 3; muldivmod++) {
1963         for (bwd = 0; bwd < 3; bwd++) {
1964             for (su = 0; su < 2; su++) {
1965                 sprintf(buffer, "_%s%s%s", 
1966                         smuldivmod[muldivmod],
1967                         ssu[su],
1968                         sbwd[bwd]);
1969                 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
1970                 SPEC_NONBANKED(__muldiv[muldivmod][bwd][su]->etype) = 1;
1971                 if (bwd < port->muldiv.force_reg_param_below) 
1972                     _makeRegParam(__muldiv[muldivmod][bwd][su]);
1973             }
1974         }
1975     }
1976 }