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