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