Break DS80C390 support into seperate port (ds390); first pass at spilling temporaries...
[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_NONBANKED(dest) |= SPEC_NONBANKED(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.model  ?
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     }
1378     return 1 ;      
1379 }
1380
1381 /*-----------------------------------------------------------------*/
1382 /* processFuncArgs - does some processing with function args       */
1383 /*-----------------------------------------------------------------*/
1384 void  processFuncArgs   (symbol *func, int ignoreName)
1385 {
1386     value *val ;
1387     int pNum = 1;   
1388     
1389
1390     /* if this function has variable argument list */
1391     /* then make the function a reentrant one      */
1392     if (func->hasVargs)
1393         SPEC_RENT(func->etype) = 1;
1394
1395     /* check if this function is defined as calleeSaves
1396        then mark it as such */
1397     func->calleeSave = inCalleeSaveList(func->name); 
1398
1399     val = func->args; /* loop thru all the arguments   */
1400         
1401     /* if it is void then remove parameters */
1402     if (val && IS_VOID(val->type)) {     
1403         func->args = NULL ;
1404         return ;
1405     }
1406
1407     /* reset regparm for the port */
1408     (*port->reset_regparms)();
1409     /* if any of the arguments is an aggregate */
1410     /* change it to pointer to the same type */
1411     while (val) {
1412         /* mark it as a register parameter if
1413            the function does not have VA_ARG
1414            and as port dictates
1415            not inhibited by command line option or #pragma */
1416         if (!func->hasVargs       &&        
1417             !options.noregparms   &&
1418             (*port->reg_parm)(val->type)) {
1419
1420             SPEC_REGPARM(val->etype) = 1;
1421         }
1422
1423 #if ENABLE_MICHAELH_REGPARM_HACK
1424         /* HACK: pull out later */
1425         if (
1426             (
1427              !strcmp(func->name, "memcpy") ||
1428              !strcmp(func->name, "strcpy") ||
1429              !strcmp(func->name, "strcmp") ||
1430              0
1431              ) &&
1432             port->reg_parm(val->type)) {
1433             SPEC_REGPARM(val->etype) = 1;
1434         }
1435 #endif                                          
1436         
1437         if ( IS_AGGREGATE(val->type)) {
1438             /* if this is a structure */
1439             /* then we need to add a new link */
1440             if (IS_STRUCT(val->type)) {
1441                                 /* first lets add DECLARATOR type */
1442                 link *p = val->type ;
1443                 
1444                 werror(W_STRUCT_AS_ARG,val->name);
1445                 val->type = newLink();
1446                 val->type->next = p ;                           
1447             }
1448             
1449             /* change to a pointer depending on the */
1450             /* storage class specified                          */
1451             switch (SPEC_SCLS(val->etype)) {
1452             case S_IDATA:
1453                 DCL_TYPE(val->type) = IPOINTER;
1454                 break;
1455             case S_PDATA:
1456                 DCL_TYPE(val->type) = PPOINTER;
1457                 break;
1458             case S_FIXED:
1459             case S_AUTO:
1460             case S_DATA:
1461             case S_REGISTER:
1462                 DCL_TYPE(val->type) = POINTER ;
1463                 break;
1464             case S_CODE:
1465                 DCL_TYPE(val->type) = CPOINTER;
1466                 break;
1467             case S_XDATA:
1468                 DCL_TYPE(val->type) = FPOINTER;
1469                 break;
1470             case S_EEPROM:
1471                 DCL_TYPE(val->type) = EEPPOINTER;
1472                 break;
1473             default :
1474                 DCL_TYPE(val->type) = GPOINTER;
1475             }
1476             
1477             /* is there is a symbol associated then */
1478             /* change the type of the symbol as well*/
1479             if ( val->sym ) {          
1480                 val->sym->type = copyLinkChain(val->type);
1481                 val->sym->etype = getSpec(val->sym->type);
1482             }
1483         }
1484         
1485         val = val->next ;
1486         pNum++;
1487     }
1488     
1489     /* if this function is reentrant or */
1490     /* automatics r 2b stacked then nothing */
1491     if (IS_RENT(func->etype) || options.stackAuto )
1492         return ;
1493     
1494     val = func->args;
1495     pNum = 1;
1496     while (val) {
1497         
1498         /* if a symbolname is not given  */
1499         /* synthesize a variable name */
1500         if (!val->sym) {
1501
1502             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1503             val->sym = newSymbol(val->name,1);
1504             SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1505             val->sym->type = copyLinkChain (val->type);
1506             val->sym->etype = getSpec (val->sym->type);
1507             val->sym->_isparm = 1;
1508             strcpy (val->sym->rname,val->name);  
1509             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1510                 SPEC_STAT(func->etype);
1511             addSymChain(val->sym);
1512    
1513         }
1514         else  /* symbol name given create synth name */      {
1515             
1516             sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1517             strcpy (val->sym->rname,val->name);
1518             val->sym->_isparm = 1;
1519             SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) = 
1520                 (options.model ? xdata : data);
1521             SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) = 
1522                 SPEC_STAT(func->etype);
1523         }
1524         val = val->next ;
1525     }
1526 }
1527
1528 /*-----------------------------------------------------------------*/
1529 /* isSymbolEqual - compares two symbols return 1 if they match     */
1530 /*-----------------------------------------------------------------*/
1531 int isSymbolEqual (symbol *dest, symbol *src)
1532 {
1533     /* if pointers match then equal */
1534     if (dest == src)
1535         return 1;
1536
1537     /* if one of them is null then don't match */
1538     if (!dest || !src)
1539         return 0;
1540     
1541     /* if both of them have rname match on rname */
1542     if (dest->rname[0] && src->rname[0]) 
1543         return (!strcmp(dest->rname,src->rname));
1544     
1545     /* otherwise match on name */
1546     return (!strcmp(dest->name,src->name));
1547 }
1548
1549 /*-----------------------------------------------------------------*/ 
1550 /* printTypeChain - prints the type chain in human readable form   */
1551 /*-----------------------------------------------------------------*/ 
1552 void printTypeChain (link *type, FILE *of)
1553 {
1554     int nlr = 0;
1555
1556     if (!of) {
1557         of = stdout;
1558         nlr = 1;
1559     }
1560
1561     while (type) {
1562         if (IS_DECL(type)) {
1563             switch (DCL_TYPE(type)) {
1564             case FUNCTION:
1565                 fprintf (of,"function ");
1566                 break;
1567             case GPOINTER:
1568                 fprintf (of,"_generic * ");
1569                 if (DCL_PTR_CONST(type))
1570                     fprintf(of,"const ");
1571                 break;          
1572             case CPOINTER:
1573                 fprintf (of,"_code * ");
1574                 if (DCL_PTR_CONST(type))
1575                     fprintf(of,"const ");
1576                 break;
1577             case FPOINTER:
1578                 fprintf (of,"_far * ");
1579                 if (DCL_PTR_CONST(type))
1580                     fprintf(of,"const ");
1581                 break;
1582             case EEPPOINTER:
1583                 fprintf (of,"_eeprom * ");
1584                 if (DCL_PTR_CONST(type))
1585                     fprintf(of,"const ");
1586                 break;
1587                 
1588             case POINTER:
1589                 fprintf (of,"_near * ");
1590                 if (DCL_PTR_CONST(type))
1591                     fprintf(of,"const ");       
1592                 break;
1593             case IPOINTER:
1594                 fprintf (of,"_idata *");
1595                 if (DCL_PTR_CONST(type))
1596                     fprintf(of,"const ");       
1597                 break; 
1598             case PPOINTER:
1599                 fprintf (of,"_pdata *");
1600                 if (DCL_PTR_CONST(type))
1601                     fprintf(of,"const ");       
1602                 break;
1603             case UPOINTER:
1604                 fprintf (of," _unkown *");
1605                 if (DCL_PTR_CONST(type))
1606                     fprintf(of,"const ");       
1607                 break;
1608                 
1609             case ARRAY :
1610                 fprintf (of,"array of ");
1611                 break;
1612             }
1613         } else { 
1614             if (SPEC_VOLATILE(type))
1615                 fprintf (of,"volatile "); 
1616             if (SPEC_USIGN(type))
1617                 fprintf (of,"unsigned ");
1618             
1619             switch (SPEC_NOUN(type)) {
1620             case V_INT:
1621                 if (IS_LONG(type))
1622                     fprintf (of,"long ");
1623                 else
1624                     if (IS_SHORT(type))
1625                         fprintf (of,"short ");
1626                     else
1627                         fprintf (of,"int ");
1628                 break;
1629
1630             case V_CHAR:
1631                 fprintf(of,"char ");
1632                 break;
1633
1634             case V_VOID:
1635                 fprintf(of,"void ");
1636                 break;
1637
1638             case V_FLOAT:
1639                 fprintf(of,"float ");
1640                 break;
1641
1642             case V_STRUCT:
1643                 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1644                 break;
1645                                   
1646             case V_SBIT:
1647                 fprintf(of,"sbit ");
1648                 break;
1649
1650             case V_BIT:
1651                 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1652                 break;
1653                 
1654             default:
1655                 break;
1656             }
1657         }
1658         type = type->next;
1659     }
1660     if (nlr)
1661         fprintf(of,"\n");
1662 }
1663
1664 /*-----------------------------------------------------------------*/ 
1665 /* cdbTypeInfo - print the type information for debugger           */
1666 /*-----------------------------------------------------------------*/
1667 void cdbTypeInfo (link *type,FILE *of)
1668 {
1669     fprintf(of,"{%d}",getSize(type));
1670     while (type) {
1671         if (IS_DECL(type)) {
1672             switch (DCL_TYPE(type)) {
1673             case FUNCTION:
1674                 fprintf (of,"DF,");
1675                 break;
1676             case GPOINTER:
1677                 fprintf (of,"DG,");             
1678                 break;          
1679             case CPOINTER:
1680                 fprintf (of,"DC,");             
1681                 break;
1682             case FPOINTER:
1683                 fprintf (of,"DX,");             
1684                 break;
1685             case POINTER:
1686                 fprintf (of,"DD,");             
1687                 break;
1688             case IPOINTER:
1689                 fprintf (of,"DI,");
1690                 break;
1691             case PPOINTER:
1692                 fprintf (of,"DP,");
1693                 break;
1694             case EEPPOINTER:
1695                 fprintf (of,"DA,");
1696                 break;
1697             case ARRAY :
1698                 fprintf (of,"DA%d,",DCL_ELEM(type));
1699                 break;
1700             default:
1701                 break;
1702             }
1703         } else { 
1704             switch (SPEC_NOUN(type)) {
1705             case V_INT:
1706                 if (IS_LONG(type))
1707                     fprintf (of,"SL");
1708                 else
1709                     if (IS_SHORT(type))
1710                         fprintf (of,"SS");
1711                     else
1712                         fprintf (of,"SI");
1713                 break;
1714
1715             case V_CHAR:
1716                 fprintf(of,"SC");
1717                 break;
1718
1719             case V_VOID:
1720                 fprintf(of,"SV");
1721                 break;
1722
1723             case V_FLOAT:
1724                 fprintf(of,"SF");
1725                 break;
1726
1727             case V_STRUCT:
1728                 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1729                 break;
1730                                   
1731             case V_SBIT:
1732                 fprintf(of,"SX");
1733                 break;
1734
1735             case V_BIT:
1736                 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1737                 break;
1738
1739             default:
1740                 break;
1741             }
1742             fputs(":",of);
1743             if (SPEC_USIGN(type))
1744                 fputs("U",of);
1745             else
1746                 fputs("S",of);
1747         }
1748         type = type->next;
1749     }
1750 }
1751 /*-----------------------------------------------------------------*/ 
1752 /* cdbSymbol - prints a symbol & its type information for debugger */
1753 /*-----------------------------------------------------------------*/ 
1754 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1755 {
1756     memmap *map;
1757
1758     if (!sym)
1759         return ;
1760     if (!of)
1761         of = stdout;
1762     
1763     if (isFunc)
1764         fprintf(of,"F:");
1765     else
1766         fprintf(of,"S:"); /* symbol record */
1767     /* if this is not a structure symbol then
1768        we need to figure out the scope information */
1769     if (!isStructSym) {
1770         if (!sym->level) {
1771             /* global */
1772             if (IS_STATIC(sym->etype))
1773                 fprintf(of,"F%s$",moduleName); /* scope is file */
1774             else
1775                 fprintf(of,"G$"); /* scope is global */
1776         }
1777         else 
1778             /* symbol is local */
1779             fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1780     } else
1781         fprintf(of,"S$"); /* scope is structure */
1782     
1783     /* print the name, & mangled name */
1784     fprintf(of,"%s$%d$%d(",sym->name,
1785             sym->level,sym->block);
1786
1787     cdbTypeInfo(sym->type,of);
1788     fprintf(of,"),");
1789     
1790     /* print the address space */
1791     map = SPEC_OCLS(sym->etype);
1792     fprintf(of,"%c,%d,%d",
1793             (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1794     
1795     /* if assigned to registers then output register names */   
1796     /* if this is a function then print
1797        if is it an interrupt routine & interrupt number
1798        and the register bank it is using */
1799     if (isFunc)
1800         fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1801                 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1802     /* alternate location to find this symbol @ : eg registers
1803        or spillication */
1804    
1805     if (!isStructSym)
1806         fprintf(of,"\n");
1807 }                   
1808
1809 /*-----------------------------------------------------------------*/ 
1810 /* cdbStruct - print a structure for debugger                      */
1811 /*-----------------------------------------------------------------*/
1812 void cdbStruct ( structdef *sdef,int block,FILE *of,
1813                  int inStruct, char *tag)
1814 {
1815     symbol *sym;
1816
1817     fprintf(of,"T:");
1818     /* if block # then must have function scope */
1819     fprintf(of,"F%s$",moduleName);
1820     fprintf(of,"%s[",(tag ? tag : sdef->tag));
1821     for (sym=sdef->fields ; sym ; sym = sym->next) {
1822         fprintf(of,"({%d}",sym->offset);
1823             cdbSymbol(sym,of,TRUE,FALSE);
1824         fprintf(of,")");
1825     }
1826     fprintf(of,"]");
1827     if (!inStruct)
1828         fprintf(of,"\n");
1829 }
1830
1831 /*------------------------------------------------------------------*/
1832 /* cdbStructBlock - calls struct printing for a blcks               */
1833 /*------------------------------------------------------------------*/
1834 void cdbStructBlock (int block , FILE *of)
1835 {    
1836     int i ;
1837     bucket **table = StructTab;
1838     bucket  *chain;
1839     
1840     /* go thru the entire  table  */
1841     for ( i = 0 ; i < 256; i++ ) {
1842         for ( chain = table[i]; chain ; chain = chain->next ) {
1843             if (chain->block >= block) {
1844                 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1845             }   
1846         }
1847     }
1848 }
1849                 
1850 /*-----------------------------------------------------------------*/ 
1851 /* powof2 - returns power of two for the number if number is pow 2 */
1852 /*-----------------------------------------------------------------*/ 
1853 int powof2 (unsigned long num)
1854 {
1855     int nshifts = 0;
1856     int n1s = 0 ;
1857     
1858     while (num) {
1859         if (num & 1) n1s++ ;
1860         num >>= 1 ;
1861         nshifts++ ;
1862     }
1863     
1864     if (n1s > 1 || nshifts == 0) return 0;
1865     return nshifts - 1 ;
1866 }
1867
1868 symbol *__fsadd ;
1869 symbol *__fssub ;
1870 symbol *__fsmul ;
1871 symbol *__fsdiv ;
1872 symbol *__fseq  ;
1873 symbol *__fsneq ;
1874 symbol *__fslt  ;
1875 symbol *__fslteq;
1876 symbol *__fsgt  ;
1877 symbol *__fsgteq;
1878
1879 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1880 symbol *__muldiv[3][3][2];
1881 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1882 link *__multypes[3][2];
1883 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1884 symbol *__conv[2][3][2];
1885
1886 link *floatType;
1887
1888 #if ENABLE_MICHAELH_REGPARM_HACK
1889 static void _makeRegParam(symbol *sym)
1890 {
1891     value *val ;
1892
1893     val = sym->args; /* loop thru all the arguments   */
1894
1895     /* reset regparm for the port */
1896     (*port->reset_regparms)();
1897     while (val) {
1898         SPEC_REGPARM(val->etype) = 1;
1899         sym->argStack -= getSize(val->type);
1900         val = val->next ;
1901     }
1902 }
1903 #endif
1904
1905 /*-----------------------------------------------------------------*/ 
1906 /* initCSupport - create functions for C support routines          */
1907 /*-----------------------------------------------------------------*/ 
1908 void initCSupport ()
1909 {
1910     const char *smuldivmod[] = {
1911         "mul", "div", "mod"
1912     };
1913     const char *sbwd[] = {
1914         "char", "int", "long"
1915     };
1916     const char *ssu[] = {
1917         "s", "u"
1918     };
1919         
1920     int bwd, su, muldivmod, tofrom;
1921
1922     floatType= newFloatLink();
1923
1924     for (bwd = 0; bwd < 3; bwd++) {
1925         link *l;
1926         switch (bwd) {
1927         case 0:
1928             l = newCharLink();
1929             break;
1930         case 1:
1931             l = newIntLink();
1932             break;
1933         case 2:
1934             l = newLongLink();
1935             break;
1936         default:
1937             assert(0);
1938         }
1939         __multypes[bwd][0] = l;
1940         __multypes[bwd][1] = copyLinkChain(l);
1941         SPEC_USIGN(__multypes[bwd][1]) = 1;
1942     }
1943
1944     __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1945     __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1946     __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1947     __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1948     __fseq  = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1949     __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1950     __fslt  = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1951     __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1952     __fsgt  = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1953     __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1954
1955     for (tofrom = 0; tofrom < 2; tofrom++) {
1956         for (bwd = 0; bwd < 3; bwd++) {
1957             for (su = 0; su < 2; su++) {
1958                 if (tofrom) {
1959                     sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1960                     __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1961                 }
1962                 else {
1963                     sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1964                     __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
1965                 }
1966             }
1967         }
1968     }
1969
1970     for (muldivmod = 0; muldivmod < 3; muldivmod++) {
1971         for (bwd = 0; bwd < 3; bwd++) {
1972             for (su = 0; su < 2; su++) {
1973                 sprintf(buffer, "_%s%s%s", 
1974                         smuldivmod[muldivmod],
1975                         ssu[su],
1976                         sbwd[bwd]);
1977                 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
1978                 SPEC_NONBANKED(__muldiv[muldivmod][bwd][su]->etype) = 1;
1979 #if ENABLE_MICHAELH_REGPARM_HACK
1980                 if (bwd < 2) 
1981                     _makeRegParam(__muldiv[muldivmod][bwd][su]);
1982 #endif
1983             }
1984         }
1985     }
1986 }