more function pointer parameter issues
[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 #include "newalloc.h"
26
27 value *aggregateToPointer (value *val);
28
29 void printFromToType(sym_link *from, sym_link *to) {
30   fprintf (stderr, "from type '");
31   printTypeChain (from, stderr);
32   fprintf (stderr, "'\nto type '");
33   printTypeChain (to, stderr);
34   fprintf (stderr, "'\n");
35 }
36
37 /* noun strings */
38 char *nounName(sym_link *sl) {
39   switch (SPEC_NOUN(sl)) 
40     {
41     case V_INT: {
42       if (SPEC_LONG(sl)) return "long";
43       if (sl->select.s._short) return "short";
44       return "int";
45     }
46     case V_FLOAT: return "float";
47     case V_CHAR: return "char";
48     case V_VOID: return "void";
49     case V_STRUCT: return "struct";
50     case V_LABEL: return "label";
51     case V_BIT: return "bit";
52     case V_SBIT: return "sbit";
53     case V_DOUBLE: return "double";
54     }
55   return "unknown";
56 };
57
58 bucket *SymbolTab[256];         /* the symbol    table  */
59 bucket *StructTab[256];         /* the structure table  */
60 bucket *TypedefTab[256];        /* the typedef   table  */
61 bucket *LabelTab[256];          /* the Label     table  */
62 bucket *enumTab[256];           /* enumerated    table  */
63
64 /*------------------------------------------------------------------*/
65 /* initSymt () - initialises symbol table related stuff             */
66 /*------------------------------------------------------------------*/
67 void 
68 initSymt ()
69 {
70   int i = 0;
71
72   for (i = 0; i < 256; i++)
73     SymbolTab[i] = StructTab[i] = (void *) NULL;
74
75
76 }
77 /*-----------------------------------------------------------------*/
78 /* newBucket - allocates & returns a new bucket        */
79 /*-----------------------------------------------------------------*/
80 bucket *
81 newBucket ()
82 {
83   bucket *bp;
84
85   bp = Safe_alloc ( sizeof (bucket));
86
87   return bp;
88 }
89
90 /*-----------------------------------------------------------------*/
91 /* hashKey - computes the hashkey given a symbol name              */
92 /*-----------------------------------------------------------------*/
93 int 
94 hashKey (const char *s)
95 {
96   unsigned long key = 0;
97
98   while (*s)
99     key += *s++;
100   return key % 256;
101 }
102
103 /*-----------------------------------------------------------------*/
104 /* addSym - adds a symbol to the hash Table                        */
105 /*-----------------------------------------------------------------*/
106 void 
107 addSym (bucket ** stab,
108         void *sym,
109         char *sname,
110         int level,
111         int block,
112         int checkType)
113 {
114   int i;                        /* index into the hash Table */
115   bucket *bp;                   /* temp bucket    *         */
116
117   if (checkType) {
118     symbol *csym = (symbol *)sym;
119
120     if (getenv("DEBUG_SANITY")) {
121       fprintf (stderr, "addSym: %s ", sname);
122     }
123     /* make sure the type is complete and sane */
124     checkTypeSanity(csym->etype, csym->name);
125   }
126
127   /* prevent overflow of the (r)name buffers */
128   if (strlen(sname)>SDCC_SYMNAME_MAX) {
129     werror (W_SYMBOL_NAME_TOO_LONG, SDCC_SYMNAME_MAX);
130     sname[SDCC_SYMNAME_MAX]='\0';
131   }
132
133   /* the symbols are always added at the head of the list  */
134   i = hashKey (sname);
135   /* get a free entry */
136   bp = Safe_alloc ( sizeof (bucket));
137
138   bp->sym = sym;                /* update the symbol pointer  */
139   bp->level = level;            /* update the nest level      */
140   bp->block = block;
141   strcpy (bp->name, sname);     /* copy the name into place */
142
143   /* if this is the first entry */
144   if (stab[i] == NULL)
145     {
146       bp->prev = bp->next = (void *) NULL;      /* point to nothing */
147       stab[i] = bp;
148     }
149   /* not first entry then add @ head of list */
150   else
151     {
152       bp->prev = NULL;
153       stab[i]->prev = bp;
154       bp->next = stab[i];
155       stab[i] = bp;
156     }
157 }
158
159 /*-----------------------------------------------------------------*/
160 /* deleteSym - deletes a symbol from the hash Table  entry     */
161 /*-----------------------------------------------------------------*/
162 void 
163 deleteSym (bucket ** stab, void *sym, char *sname)
164 {
165   int i = 0;
166   bucket *bp;
167
168   i = hashKey (sname);
169
170   bp = stab[i];
171   /* find the symbol */
172   while (bp)
173     {
174       if (bp->sym == sym)       /* found it then break out */
175         break;                  /* of the loop       */
176       bp = bp->next;
177     }
178
179   if (!bp)                      /* did not find it */
180     return;
181   /* if this is the first one in the chain */
182   if (!bp->prev)
183     {
184       stab[i] = bp->next;
185       if (stab[i])              /* if chain ! empty */
186         stab[i]->prev = (void *) NULL;
187     }
188   /* middle || end of chain */
189   else
190     {
191       if (bp->next)             /* if not end of chain */
192         bp->next->prev = bp->prev;
193
194       bp->prev->next = bp->next;
195     }
196
197 }
198
199 /*-----------------------------------------------------------------*/
200 /* findSym - finds a symbol in a table           */
201 /*-----------------------------------------------------------------*/
202 void *
203 findSym (bucket ** stab, void *sym, const char *sname)
204 {
205   bucket *bp;
206
207   bp = stab[hashKey (sname)];
208   while (bp)
209     {
210       if (bp->sym == sym || strcmp (bp->name, sname) == 0)
211         break;
212       bp = bp->next;
213     }
214
215   return (bp ? bp->sym : (void *) NULL);
216 }
217
218 /*-----------------------------------------------------------------*/
219 /* findSymWithLevel - finds a symbol with a name & level           */
220 /*-----------------------------------------------------------------*/
221 void *
222 findSymWithLevel (bucket ** stab, symbol * sym)
223 {
224   bucket *bp;
225
226   bp = stab[hashKey (sym->name)];
227
228   /**
229    **  do the search from the head of the list since the
230    **  elements are added at the head it is ensured that
231    ** we will find the deeper definitions before we find
232    ** the global ones. we need to check for symbols with
233    ** level <= to the level given, if levels match then block
234    ** numbers need to match as well
235    **/
236   while (bp)
237     {
238       if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
239         {
240           /* if this is parameter then nothing else need to be checked */
241           if (((symbol *) (bp->sym))->_isparm)
242             return (bp->sym);
243           /* if levels match then block numbers should also match */
244           if (bp->level && bp->level == sym->level && bp->block == sym->block)
245             return (bp->sym);
246           /* if levels don't match then we are okay */
247           if (bp->level && bp->level != sym->level && bp->block <= sym->block)
248             return (bp->sym);
249           /* if this is a global variable then we are ok too */
250           if (bp->level == 0)
251             return (bp->sym);
252         }
253
254       bp = bp->next;
255     }
256
257   return (void *) NULL;
258 }
259
260 /*-----------------------------------------------------------------*/
261 /* findSymWithBlock - finds a symbol with name in with a block     */
262 /*-----------------------------------------------------------------*/
263 void *
264 findSymWithBlock (bucket ** stab, symbol * sym, int block)
265 {
266   bucket *bp;
267
268   bp = stab[hashKey (sym->name)];
269   while (bp)
270     {
271       if (strcmp (bp->name, sym->name) == 0 &&
272           bp->block <= block)
273         break;
274       bp = bp->next;
275     }
276
277   return (bp ? bp->sym : (void *) NULL);
278 }
279
280 /*------------------------------------------------------------------*/
281 /* newSymbol () - returns a new pointer to a symbol                 */
282 /*------------------------------------------------------------------*/
283 symbol *
284 newSymbol (char *name, int scope)
285 {
286   symbol *sym;
287
288   sym = Safe_alloc ( sizeof (symbol));
289
290   strcpy (sym->name, name);     /* copy the name    */
291   sym->level = scope;           /* set the level    */
292   sym->block = currBlockno;
293   sym->lineDef = yylineno;      /* set the line number */
294   return sym;
295 }
296
297 /*------------------------------------------------------------------*/
298 /* newLink - creates a new link (declarator,specifier)              */
299 /*------------------------------------------------------------------*/
300 sym_link *
301 newLink ()
302 {
303   sym_link *p;
304
305   p = Safe_alloc ( sizeof (sym_link));
306
307   return p;
308 }
309
310 /*------------------------------------------------------------------*/
311 /* newStruct - creats a new structdef from the free list            */
312 /*------------------------------------------------------------------*/
313 structdef *
314 newStruct (char *tag)
315 {
316   structdef *s;
317
318   s = Safe_alloc ( sizeof (structdef));
319
320   strcpy (s->tag, tag);         /* copy the tag            */
321   return s;
322 }
323
324 /*------------------------------------------------------------------*/
325 /* pointerTypes - do the computation for the pointer types          */
326 /*------------------------------------------------------------------*/
327 void 
328 pointerTypes (sym_link * ptr, sym_link * type)
329 {
330   if (IS_SPEC (ptr))
331     return;
332
333   /* find the first pointer type */
334   while (ptr && !IS_PTR (ptr))
335     ptr = ptr->next;
336
337   /* could not find it */
338   if (!ptr || IS_SPEC (ptr))
339     return;
340   
341   if (IS_PTR(ptr) && DCL_TYPE(ptr)!=UPOINTER) {
342     pointerTypes (ptr->next, type);
343     return;
344   }
345
346   /* change the pointer type depending on the
347      storage class of the type */
348   if (IS_SPEC (type))
349     {
350       DCL_PTR_CONST (ptr) = SPEC_CONST (type);
351       DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type);
352       switch (SPEC_SCLS (type))
353         {
354         case S_XDATA:
355           DCL_TYPE (ptr) = FPOINTER;
356           break;
357         case S_IDATA:
358           DCL_TYPE (ptr) = IPOINTER;
359           break;
360         case S_PDATA:
361           DCL_TYPE (ptr) = PPOINTER;
362           break;
363         case S_DATA:
364           DCL_TYPE (ptr) = POINTER;
365           break;
366         case S_CODE:
367           DCL_PTR_CONST (ptr) = port->mem.code_ro;
368           DCL_TYPE (ptr) = CPOINTER;
369           break;
370         case S_EEPROM:
371           DCL_TYPE (ptr) = EEPPOINTER;
372           break;
373         default:
374           DCL_TYPE (ptr) = GPOINTER;
375           break;
376         }
377       /* the storage class of type ends here */
378       SPEC_SCLS (type) =
379         SPEC_CONST (type) =
380         SPEC_VOLATILE (type) = 0;
381     }
382
383   /* now change all the remaining unknown pointers
384      to generic pointers */
385   while (ptr)
386     {
387       if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
388         DCL_TYPE (ptr) = GPOINTER;
389       ptr = ptr->next;
390     }
391
392   /* same for the type although it is highly unlikely that
393      type will have a pointer */
394   while (type)
395     {
396       if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
397         DCL_TYPE (type) = GPOINTER;
398       type = type->next;
399     }
400
401 }
402
403 /*------------------------------------------------------------------*/
404 /* addDecl - adds a declarator @ the end of a chain                 */
405 /*------------------------------------------------------------------*/
406 void 
407 addDecl (symbol * sym, int type, sym_link * p)
408 {
409   sym_link *head;
410   sym_link *tail;
411   sym_link *t;
412
413   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
414     fprintf (stderr, "SDCCsymt.c:addDecl(%s,%d,%p)\n", sym->name, type, p);
415
416   /* if we are passed a link then set head & tail */
417   if (p)
418     {
419       tail = head = p;
420       while (tail->next)
421         tail = tail->next;
422     }
423   else
424     {
425       head = tail = newLink ();
426       DCL_TYPE (head) = type;
427     }
428
429   /* if this is the first entry   */
430   if (!sym->type)
431     {
432       sym->type = head;
433       sym->etype = tail;
434     }
435   else
436     {
437       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
438         {
439           sym->etype = mergeSpec (sym->etype, head, sym->name);
440         }
441       else
442         {
443           if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
444             {
445               t = sym->type;
446               while (t->next != sym->etype)
447                 t = t->next;
448               t->next = head;
449               tail->next = sym->etype;
450             }
451           else
452             {
453               sym->etype->next = head;
454               sym->etype = tail;
455             }
456         }
457     }
458
459   /* if the type is an unknown pointer and has
460      a tspec then take the storage class const & volatile
461      attribute from the tspec & make it those of this
462      symbol */
463   if (p &&
464       !IS_SPEC (p) &&
465       //DCL_TYPE (p) == UPOINTER &&
466       DCL_TSPEC (p))
467     {
468       if (!IS_SPEC (sym->etype))
469         {
470           sym->etype = sym->etype->next = newLink ();
471           sym->etype->class = SPECIFIER;
472         }
473       SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
474       SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p));
475       SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
476       DCL_TSPEC (p) = NULL;
477     }
478
479   // if there is a function in this type chain
480   if (p && funcInChain(sym->type)) {
481     processFuncArgs (sym);
482   }
483
484   return;
485 }
486
487 /*------------------------------------------------------------------
488   checkTypeSanity: prevent the user from doing e.g.:
489   unsigned float uf;
490   ------------------------------------------------------------------*/
491 void checkTypeSanity(sym_link *etype, char *name) {
492   char *noun;
493
494   if (!etype) {
495     if (getenv("DEBUG_SANITY")) {
496       fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
497     }
498     return;
499   }
500
501   if (!IS_SPEC(etype)) {
502     if (getenv("DEBUG_SANITY")) {
503       fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
504     }
505     return;
506   }
507
508   noun=nounName(etype);
509
510   if (getenv("DEBUG_SANITY")) {
511     fprintf (stderr, "checking sanity for %s %x\n", name, (int)etype);
512   }
513
514   if ((SPEC_NOUN(etype)==V_CHAR || 
515        SPEC_NOUN(etype)==V_FLOAT || 
516        SPEC_NOUN(etype)==V_DOUBLE || 
517        SPEC_NOUN(etype)==V_VOID) &&
518       (etype->select.s._short || SPEC_LONG(etype))) {
519     // long or short for char float double or void
520     werror (E_LONG_OR_SHORT_INVALID, noun, name);
521   }
522   if ((SPEC_NOUN(etype)==V_FLOAT || 
523        SPEC_NOUN(etype)==V_DOUBLE || 
524        SPEC_NOUN(etype)==V_VOID) && 
525       (etype->select.s._signed || SPEC_USIGN(etype))) {
526     // signed or unsigned for float double or void
527     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
528   }
529
530   // special case for "short"
531   if (etype->select.s._short) {
532     SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
533     etype->select.s._short = 0;
534   }
535
536   /* if no noun e.g. 
537      "const a;" or "data b;" or "signed s" or "long l"
538      assume an int */
539   if (!SPEC_NOUN(etype)) {
540     SPEC_NOUN(etype)=V_INT;
541   }
542
543   if (etype->select.s._signed && SPEC_USIGN(etype)) {
544     // signed AND unsigned 
545     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
546   }
547   if (etype->select.s._short && SPEC_LONG(etype)) {
548     // short AND long
549     werror (E_LONG_AND_SHORT_INVALID, noun, name);
550   }
551
552 }
553
554 /*------------------------------------------------------------------*/
555 /* mergeSpec - merges two specifiers and returns the new one        */
556 /*------------------------------------------------------------------*/
557 sym_link *
558 mergeSpec (sym_link * dest, sym_link * src, char *name)
559 {
560   sym_link *symlink=dest;
561
562   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
563 #if 0
564     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
565     exit (1);
566 #else
567     werror (E_SYNTAX_ERROR, yytext);
568     // the show must go on
569     return newIntLink();
570 #endif
571   }
572
573   if (SPEC_NOUN(src)) {
574     if (!SPEC_NOUN(dest)) {
575       SPEC_NOUN(dest)=SPEC_NOUN(src);
576     } else {
577       /* we shouldn't redeclare the type */
578       if (getenv("DEBUG_SANITY")) {
579         fprintf (stderr, "mergeSpec: ");
580       }
581       werror(E_TWO_OR_MORE_DATA_TYPES, name);
582     }
583   }
584   
585   if (SPEC_SCLS(src)) {
586     /* if destination has no storage class */
587     if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
588       SPEC_SCLS (dest) = SPEC_SCLS (src);
589     } else {
590       if (getenv("DEBUG_SANITY")) {
591         fprintf (stderr, "mergeSpec: ");
592       }
593       werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
594     }
595   }
596
597   /* copy all the specifications  */
598
599   // we really should do: 
600 #if 0
601   if (SPEC_what(src)) {
602     if (SPEC_what(dest)) {
603       werror(W_DUPLICATE_SPEC, "what");
604     }
605     SPEC_what(dst)|=SPEC_what(src);
606   }
607 #endif
608   // but there are more important thing right now
609
610   SPEC_LONG (dest) |= SPEC_LONG (src);
611   dest->select.s._short|=src->select.s._short;
612   SPEC_USIGN (dest) |= SPEC_USIGN (src);
613   dest->select.s._signed|=src->select.s._signed;
614   SPEC_STAT (dest) |= SPEC_STAT (src);
615   SPEC_EXTR (dest) |= SPEC_EXTR (src);
616   SPEC_CONST(dest) |= SPEC_CONST (src);
617   SPEC_ABSA (dest) |= SPEC_ABSA (src);
618   SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
619   SPEC_ADDR (dest) |= SPEC_ADDR (src);
620   SPEC_OCLS (dest) = SPEC_OCLS (src);
621   SPEC_BLEN (dest) |= SPEC_BLEN (src);
622   SPEC_BSTR (dest) |= SPEC_BSTR (src);
623   SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
624
625   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
626     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
627
628   /* these are the only function attributes that will be set 
629      in a specifier while parsing */
630   FUNC_NONBANKED(dest) |= FUNC_NONBANKED(src);
631   FUNC_BANKED(dest) |= FUNC_BANKED(src);
632   FUNC_ISCRITICAL(dest) |= FUNC_ISCRITICAL(src);
633   FUNC_ISREENT(dest) |= FUNC_ISREENT(src);
634   FUNC_ISNAKED(dest) |= FUNC_ISNAKED(src);
635   FUNC_ISISR(dest) |= FUNC_ISISR(src);
636   FUNC_INTNO(dest) |= FUNC_INTNO(src);
637   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
638
639   return symlink;
640 }
641
642 /*------------------------------------------------------------------*/
643 /* cloneSpec - copies the entire spec and returns a new spec        */
644 /*------------------------------------------------------------------*/
645 sym_link *
646 cloneSpec (sym_link * src)
647 {
648   sym_link *spec;
649
650   /* go thru chain till we find the specifier */
651   while (src && src->class != SPECIFIER)
652     src = src->next;
653
654   spec = newLink ();
655   memcpy (spec, src, sizeof (sym_link));
656   return spec;
657 }
658
659 /*------------------------------------------------------------------*/
660 /* genSymName - generates and returns a name used for anonymous vars */
661 /*------------------------------------------------------------------*/
662 char *
663 genSymName (int level)
664 {
665   static int gCount = 0;
666   static char gname[SDCC_NAME_MAX + 1];
667
668   sprintf (gname, "__%04d%04d", level, gCount++);
669   return gname;
670 }
671
672 /*------------------------------------------------------------------*/
673 /* getSpec - returns the specifier part from a declaration chain    */
674 /*------------------------------------------------------------------*/
675 sym_link *
676 getSpec (sym_link * p)
677 {
678   sym_link *loop;
679
680   loop = p;
681   while (p && !(IS_SPEC (p)))
682     p = p->next;
683
684   return p;
685 }
686
687 /*------------------------------------------------------------------*/
688 /* newCharLink() - creates an char type                             */
689 /*------------------------------------------------------------------*/
690 sym_link *
691 newCharLink ()
692 {
693   sym_link *p;
694
695   p = newLink ();
696   p->class = SPECIFIER;
697   SPEC_NOUN (p) = V_CHAR;
698
699   return p;
700 }
701
702 /*------------------------------------------------------------------*/
703 /* newFloatLink - a new Float type                                  */
704 /*------------------------------------------------------------------*/
705 sym_link *
706 newFloatLink ()
707 {
708   sym_link *p;
709
710   p = newLink ();
711   p->class = SPECIFIER;
712   SPEC_NOUN (p) = V_FLOAT;
713
714   return p;
715 }
716
717 /*------------------------------------------------------------------*/
718 /* newLongLink() - new long type                                    */
719 /*------------------------------------------------------------------*/
720 sym_link *
721 newLongLink ()
722 {
723   sym_link *p;
724
725   p = newLink ();
726   p->class = SPECIFIER;
727   SPEC_NOUN (p) = V_INT;
728   SPEC_LONG (p) = 1;
729
730   return p;
731 }
732
733 /*------------------------------------------------------------------*/
734 /* newIntLink() - creates an int type                               */
735 /*------------------------------------------------------------------*/
736 sym_link *
737 newIntLink ()
738 {
739   sym_link *p;
740
741   p = newLink ();
742   p->class = SPECIFIER;
743   SPEC_NOUN (p) = V_INT;
744
745   return p;
746 }
747
748 /*------------------------------------------------------------------*/
749 /* getSize - returns size of a type chain in bits                   */
750 /*------------------------------------------------------------------*/
751 unsigned int 
752 getSize (sym_link * p)
753 {
754   /* if nothing return 0 */
755   if (!p)
756     return 0;
757   if (IS_SPEC (p))
758     {                           /* if this is the specifier then */
759       switch (SPEC_NOUN (p))
760         {                       /* depending on the specifier type */
761         case V_INT:
762           return (IS_LONG (p) ? LONGSIZE : INTSIZE);
763         case V_FLOAT:
764           return FLOATSIZE;
765         case V_CHAR:
766           return CHARSIZE;
767         case V_VOID:
768           return 0;
769         case V_STRUCT:
770           return SPEC_STRUCT (p)->size;
771         case V_LABEL:
772           return 0;
773         case V_SBIT:
774           return BITSIZE;
775         case V_BIT:
776           return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
777         default:
778           return 0;
779         }
780     }
781
782   /* this is a specifier  */
783   switch (DCL_TYPE (p))
784     {
785     case FUNCTION:
786       return 2;
787     case ARRAY:
788       return DCL_ELEM (p) * getSize (p->next);
789     case IPOINTER:
790     case PPOINTER:
791     case POINTER:
792       return (PTRSIZE);
793     case EEPPOINTER:
794     case FPOINTER:
795     case CPOINTER:
796       return (FPTRSIZE);
797     case GPOINTER:
798       return (GPTRSIZE);
799
800     default:
801       return 0;
802     }
803 }
804
805 /*------------------------------------------------------------------*/
806 /* bitsForType - returns # of bits required to store this type      */
807 /*------------------------------------------------------------------*/
808 unsigned int 
809 bitsForType (sym_link * p)
810 {
811   /* if nothing return 0 */
812   if (!p)
813     return 0;
814
815   if (IS_SPEC (p))
816     {                           /* if this is the specifier then */
817
818       switch (SPEC_NOUN (p))
819         {                       /* depending on the specifier type */
820         case V_INT:
821           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
822         case V_FLOAT:
823           return FLOATSIZE * 8;
824         case V_CHAR:
825           return CHARSIZE * 8;
826         case V_VOID:
827           return 0;
828         case V_STRUCT:
829           return SPEC_STRUCT (p)->size * 8;
830         case V_LABEL:
831           return 0;
832         case V_SBIT:
833           return 1;
834         case V_BIT:
835           return SPEC_BLEN (p);
836         default:
837           return 0;
838         }
839     }
840
841   /* this is a specifier  */
842   switch (DCL_TYPE (p))
843     {
844     case FUNCTION:
845       return 2;
846     case ARRAY:
847       return DCL_ELEM (p) * getSize (p->next) * 8;
848     case IPOINTER:
849     case PPOINTER:
850     case POINTER:
851       return (PTRSIZE * 8);
852     case EEPPOINTER:
853     case FPOINTER:
854     case CPOINTER:
855       return (FPTRSIZE * 8);
856     case GPOINTER:
857       return (GPTRSIZE * 8);
858
859     default:
860       return 0;
861     }
862 }
863
864 /*------------------------------------------------------------------*/
865 /* copySymbolChain - copies a symbol chain                          */
866 /*------------------------------------------------------------------*/
867 symbol *
868 copySymbolChain (symbol * src)
869 {
870   symbol *dest;
871
872   if (!src)
873     return NULL;
874
875   dest = copySymbol (src);
876   dest->next = copySymbolChain (src->next);
877   return dest;
878 }
879
880 /*------------------------------------------------------------------*/
881 /* copySymbol - makes a copy of a symbol                            */
882 /*------------------------------------------------------------------*/
883 symbol *
884 copySymbol (symbol * src)
885 {
886   symbol *dest;
887
888   if (!src)
889     return NULL;
890
891   dest = newSymbol (src->name, src->level);
892   memcpy (dest, src, sizeof (symbol));
893   dest->level = src->level;
894   dest->block = src->block;
895   dest->ival = copyIlist (src->ival);
896   dest->type = copyLinkChain (src->type);
897   dest->etype = getSpec (dest->type);
898   dest->next = NULL;
899   dest->key = src->key;
900   dest->allocreq = src->allocreq;
901   return dest;
902 }
903
904 /*------------------------------------------------------------------*/
905 /* reverseSyms - reverses the links for a symbol chain      */
906 /*------------------------------------------------------------------*/
907 symbol *
908 reverseSyms (symbol * sym)
909 {
910   symbol *prev, *curr, *next;
911
912   if (!sym)
913     return NULL;
914
915   prev = sym;
916   curr = sym->next;
917
918   while (curr)
919     {
920       next = curr->next;
921       curr->next = prev;
922       prev = curr;
923       curr = next;
924     }
925   sym->next = (void *) NULL;
926   return prev;
927 }
928
929 /*------------------------------------------------------------------*/
930 /* reverseLink - reverses the links for a type chain        */
931 /*------------------------------------------------------------------*/
932 sym_link *
933 reverseLink (sym_link * type)
934 {
935   sym_link *prev, *curr, *next;
936
937   if (!type)
938     return NULL;
939
940   prev = type;
941   curr = type->next;
942
943   while (curr)
944     {
945       next = curr->next;
946       curr->next = prev;
947       prev = curr;
948       curr = next;
949     }
950   type->next = (void *) NULL;
951   return prev;
952 }
953
954 /*------------------------------------------------------------------*/
955 /* addSymChain - adds a symbol chain to the symboltable             */
956 /*------------------------------------------------------------------*/
957 void 
958 addSymChain (symbol * symHead)
959 {
960   symbol *sym = symHead;
961   symbol *csym = NULL;
962
963   for (; sym != NULL; sym = sym->next)
964     {
965       changePointer(sym);
966       checkTypeSanity(sym->etype, sym->name);
967
968       /* if already exists in the symbol table then check if
969          one of them is an extern definition if yes then
970          then check if the type match, if the types match then
971          delete the current entry and add the new entry      */
972       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
973           csym->level == sym->level) {
974         
975         /* one definition extern ? */
976         if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
977           /* do types match ? */
978           if (compareType (csym->type, sym->type) != 1) {
979             /* no then error */
980             werror (E_EXTERN_MISMATCH, csym->name);
981             continue;
982           }
983           /* delete current entry */
984           deleteSym (SymbolTab, csym, csym->name);
985         } else {
986           /* not extern */
987           werror (E_DUPLICATE, sym->name);
988           continue;
989         }
990       }
991
992       /* add new entry */
993       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
994     }
995 }
996
997
998 /*------------------------------------------------------------------*/
999 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
1000 /*------------------------------------------------------------------*/
1001 int 
1002 funcInChain (sym_link * lnk)
1003 {
1004   while (lnk)
1005     {
1006       if (IS_FUNC (lnk))
1007         return 1;
1008       lnk = lnk->next;
1009     }
1010   return 0;
1011 }
1012
1013 /*------------------------------------------------------------------*/
1014 /* structElemType - returns the type info of a sturct member        */
1015 /*------------------------------------------------------------------*/
1016 sym_link *
1017 structElemType (sym_link * stype, value * id)
1018 {
1019   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1020   sym_link *type, *etype;
1021   sym_link *petype = getSpec (stype);
1022
1023   if (!fields || !id)
1024     return NULL;
1025
1026   /* look for the id */
1027   while (fields)
1028     {
1029       if (strcmp (fields->rname, id->name) == 0)
1030         {
1031           type = copyLinkChain (fields->type);
1032           etype = getSpec (type);
1033           SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1034                                SPEC_SCLS (etype) : SPEC_SCLS (petype));
1035           return type;
1036         }
1037       fields = fields->next;
1038     }
1039   werror (E_NOT_MEMBER, id->name);
1040
1041   return NULL;
1042 }
1043
1044 /*------------------------------------------------------------------*/
1045 /* getStructElement - returns element of a tructure definition      */
1046 /*------------------------------------------------------------------*/
1047 symbol *
1048 getStructElement (structdef * sdef, symbol * sym)
1049 {
1050   symbol *field;
1051
1052   for (field = sdef->fields; field; field = field->next)
1053     if (strcmp (field->name, sym->name) == 0)
1054       return field;
1055
1056   werror (E_NOT_MEMBER, sym->name);
1057
1058   return sdef->fields;
1059 }
1060
1061 /*------------------------------------------------------------------*/
1062 /* compStructSize - computes the size of a structure                */
1063 /*------------------------------------------------------------------*/
1064 int 
1065 compStructSize (int su, structdef * sdef)
1066 {
1067     int sum = 0, usum = 0;
1068     int bitOffset = 0;
1069     symbol *loop;
1070
1071     /* for the identifiers  */
1072     loop = sdef->fields;
1073     while (loop) {
1074
1075         /* create the internal name for this variable */
1076         sprintf (loop->rname, "_%s", loop->name);
1077         loop->offset = (su == UNION ? sum = 0 : sum);
1078         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1079
1080         /* if this is a bit field  */
1081         if (loop->bitVar) {
1082
1083             /* change it to a unsigned bit */
1084             SPEC_NOUN (loop->etype) = V_BIT;
1085             SPEC_USIGN (loop->etype) = 1;
1086             /* check if this fit into the remaining   */
1087             /* bits of this byte else align it to the */
1088             /* next byte boundary                     */
1089             if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
1090                 SPEC_BSTR (loop->etype) = bitOffset;
1091                 if ((bitOffset += (loop->bitVar % 8)) == 8)
1092                     sum++;
1093             }
1094             else /* does not fit */ {
1095                 bitOffset = 0;
1096                 SPEC_BSTR (loop->etype) = bitOffset;
1097                 sum += (loop->bitVar / 8);
1098                 bitOffset += (loop->bitVar % 8);
1099             }
1100             /* if this is the last field then pad */
1101             if (!loop->next && bitOffset && bitOffset != 8) {
1102                 bitOffset = 0;
1103                 sum++;
1104             }
1105         }
1106         else {
1107             checkDecl (loop, 1);
1108             sum += getSize (loop->type);
1109         }
1110
1111 #if 0 // jwk: this is done now in addDecl()
1112         /* if function then do the arguments for it */
1113         if (funcInChain (loop->type)) {
1114             processFuncArgs (loop);
1115         }
1116 #endif
1117
1118         loop = loop->next;
1119
1120         /* if this is not a bitfield but the */
1121         /* previous one was and did not take */
1122         /* the whole byte then pad the rest  */
1123         if ((loop && !loop->bitVar) && bitOffset) {
1124             bitOffset = 0;
1125             sum++;
1126         }
1127
1128         /* if union then size = sizeof larget field */
1129         if (su == UNION)
1130             usum = max (usum, sum);
1131
1132     }
1133
1134     return (su == UNION ? usum : sum);
1135 }
1136
1137 /*------------------------------------------------------------------*/
1138 /* checkSClass - check the storage class specification              */
1139 /*------------------------------------------------------------------*/
1140 static void 
1141 checkSClass (symbol * sym, int isProto)
1142 {
1143   if (getenv("DEBUG_SANITY")) {
1144     fprintf (stderr, "checkSClass: %s \n", sym->name);
1145   }
1146   
1147   /* type is literal can happen foe enums change
1148      to auto */
1149   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1150     SPEC_SCLS (sym->etype) = S_AUTO;
1151   
1152   /* if sfr or sbit then must also be */
1153   /* volatile the initial value will be xlated */
1154   /* to an absolute address */
1155   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1156       SPEC_SCLS (sym->etype) == S_SFR)
1157     {
1158       SPEC_VOLATILE (sym->etype) = 1;
1159       /* if initial value given */
1160       if (sym->ival)
1161         {
1162           SPEC_ABSA (sym->etype) = 1;
1163           SPEC_ADDR (sym->etype) =
1164             (int) list2int (sym->ival);
1165           sym->ival = NULL;
1166         }
1167     }
1168   
1169   /* if absolute address given then it mark it as
1170      volatile */
1171   if (IS_ABSOLUTE (sym->etype))
1172     SPEC_VOLATILE (sym->etype) = 1;
1173   
1174   /* global variables declared const put into code */
1175   if (sym->level == 0 &&
1176       SPEC_CONST (sym->etype)) {
1177     SPEC_SCLS (sym->etype) = S_CODE;
1178   }
1179   
1180   /* global variable in code space is a constant */
1181   if (sym->level == 0 &&
1182       SPEC_SCLS (sym->etype) == S_CODE &&
1183       port->mem.code_ro)
1184     SPEC_CONST (sym->etype) = 1;
1185   
1186
1187   /* if bit variable then no storage class can be */
1188   /* specified since bit is already a storage */
1189   if (IS_BITVAR (sym->etype) &&
1190       (SPEC_SCLS (sym->etype) != S_FIXED &&
1191        SPEC_SCLS (sym->etype) != S_SBIT &&
1192        SPEC_SCLS (sym->etype) != S_BIT)
1193     )
1194     {
1195       werror (E_BITVAR_STORAGE, sym->name);
1196       SPEC_SCLS (sym->etype) = S_FIXED;
1197     }
1198
1199   /* extern variables cannot be initialized */
1200   if (IS_EXTERN (sym->etype) && sym->ival)
1201     {
1202       werror (E_EXTERN_INIT, sym->name);
1203       sym->ival = NULL;
1204     }
1205
1206   /* if this is an atomatic symbol */
1207   if (sym->level && (options.stackAuto || reentrant)) {
1208     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1209          SPEC_SCLS (sym->etype) == S_FIXED ||
1210          SPEC_SCLS (sym->etype) == S_REGISTER ||
1211          SPEC_SCLS (sym->etype) == S_STACK ||
1212          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1213       SPEC_SCLS (sym->etype) = S_AUTO;
1214     } else {
1215       /* storage class may only be specified for statics */
1216       if (!IS_STATIC(sym->etype)) {
1217         werror (E_AUTO_ASSUMED, sym->name);
1218       }
1219     }
1220   }
1221   
1222   /* automatic symbols cannot be given   */
1223   /* an absolute address ignore it      */
1224   if (sym->level &&
1225       SPEC_ABSA (sym->etype) &&
1226       (options.stackAuto || reentrant))
1227     {
1228       werror (E_AUTO_ABSA, sym->name);
1229       SPEC_ABSA (sym->etype) = 0;
1230     }
1231
1232   /* arrays & pointers cannot be defined for bits   */
1233   /* SBITS or SFRs or BIT                           */
1234   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1235       (SPEC_NOUN (sym->etype) == V_BIT ||
1236        SPEC_NOUN (sym->etype) == V_SBIT ||
1237        SPEC_SCLS (sym->etype) == S_SFR))
1238     werror (E_BIT_ARRAY, sym->name);
1239
1240   /* if this is a bit|sbit then set length & start  */
1241   if (SPEC_NOUN (sym->etype) == V_BIT ||
1242       SPEC_NOUN (sym->etype) == V_SBIT)
1243     {
1244       SPEC_BLEN (sym->etype) = 1;
1245       SPEC_BSTR (sym->etype) = 0;
1246     }
1247
1248   if (!isProto) {
1249     /* variables declared in CODE space must have */
1250     /* initializers if not an extern */
1251     if (SPEC_SCLS (sym->etype) == S_CODE &&
1252         sym->ival == NULL &&
1253         //!sym->level &&
1254         port->mem.code_ro &&
1255         !IS_EXTERN (sym->etype) &&
1256         !funcInChain (sym->type))
1257       werror (E_CODE_NO_INIT, sym->name);
1258   }
1259
1260   /* if parameter or local variable then change */
1261   /* the storage class to reflect where the var will go */
1262   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1263       !IS_STATIC(sym->etype))
1264     {
1265       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1266         {
1267           SPEC_SCLS (sym->etype) = (options.useXstack ?
1268                                     S_XSTACK : S_STACK);
1269         }
1270       else
1271         {
1272           /* hack-o-matic! I see no reason why the useXstack option should ever
1273            * control this allcoation, but the code was originally that way, and
1274            * changing it for non-390 ports breaks the compiler badly.
1275            */
1276           bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1277           SPEC_SCLS (sym->etype) = (useXdata ?
1278                                     S_XDATA : S_FIXED);
1279         }
1280     }
1281 }
1282
1283 /*------------------------------------------------------------------*/
1284 /* changePointer - change pointer to functions                      */
1285 /*------------------------------------------------------------------*/
1286 void 
1287 changePointer (symbol * sym)
1288 {
1289   sym_link *p;
1290
1291   /* go thru the chain of declarations   */
1292   /* if we find a pointer to a function  */
1293   /* unconditionally change it to a ptr  */
1294   /* to code area                        */
1295   for (p = sym->type; p; p = p->next)
1296     {
1297       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1298         DCL_TYPE (p) = GPOINTER;
1299       if (IS_PTR (p) && IS_FUNC (p->next))
1300         DCL_TYPE (p) = CPOINTER;
1301     }
1302 }
1303
1304 /*------------------------------------------------------------------*/
1305 /* checkDecl - does semantic validation of a declaration                   */
1306 /*------------------------------------------------------------------*/
1307 int 
1308 checkDecl (symbol * sym, int isProto)
1309 {
1310
1311   checkSClass (sym, isProto);           /* check the storage class      */
1312   changePointer (sym);          /* change pointers if required */
1313
1314   /* if this is an array without any dimension
1315      then update the dimension from the initial value */
1316   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1317     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1318
1319   return 0;
1320 }
1321
1322 /*------------------------------------------------------------------*/
1323 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1324 /*------------------------------------------------------------------*/
1325 sym_link *
1326 copyLinkChain (sym_link * p)
1327 {
1328   sym_link *head, *curr, *loop;
1329
1330   curr = p;
1331   head = loop = (curr ? newLink () : (void *) NULL);
1332   while (curr)
1333     {
1334       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1335       loop->next = (curr->next ? newLink () : (void *) NULL);
1336       loop = loop->next;
1337       curr = curr->next;
1338     }
1339
1340   return head;
1341 }
1342
1343
1344 /*------------------------------------------------------------------*/
1345 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1346 /*                symbols in the given block                        */
1347 /*------------------------------------------------------------------*/
1348 void 
1349 cleanUpBlock (bucket ** table, int block)
1350 {
1351   int i;
1352   bucket *chain;
1353
1354   /* go thru the entire  table  */
1355   for (i = 0; i < 256; i++)
1356     {
1357       for (chain = table[i]; chain; chain = chain->next)
1358         {
1359           if (chain->block >= block)
1360             {
1361               deleteSym (table, chain->sym, chain->name);
1362             }
1363         }
1364     }
1365 }
1366
1367 /*------------------------------------------------------------------*/
1368 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1369 /*                symbols in the given level                        */
1370 /*------------------------------------------------------------------*/
1371 void 
1372 cleanUpLevel (bucket ** table, int level)
1373 {
1374   int i;
1375   bucket *chain;
1376
1377   /* go thru the entire  table  */
1378   for (i = 0; i < 256; i++)
1379     {
1380       for (chain = table[i]; chain; chain = chain->next)
1381         {
1382           if (chain->level >= level)
1383             {
1384               deleteSym (table, chain->sym, chain->name);
1385             }
1386         }
1387     }
1388 }
1389
1390 /*------------------------------------------------------------------*/
1391 /* computeType - computes the resultant type from two types         */
1392 /*------------------------------------------------------------------*/
1393 sym_link *
1394 computeType (sym_link * type1, sym_link * type2)
1395 {
1396   sym_link *rType;
1397   sym_link *reType;
1398   sym_link *etype1 = getSpec (type1);
1399   sym_link *etype2 = getSpec (type2);
1400
1401   /* if one of them is a float then result is a float */
1402   /* here we assume that the types passed are okay */
1403   /* and can be cast to one another                */
1404   /* which ever is greater in size */
1405   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1406     rType = newFloatLink ();
1407   else
1408     /* if only one of them is a bit variable
1409        then the other one prevails */
1410   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1411     rType = copyLinkChain (type2);
1412   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1413     rType = copyLinkChain (type1);
1414   else
1415     /* if one of them is a pointer then that
1416        prevails */
1417   if (IS_PTR (type1))
1418     rType = copyLinkChain (type1);
1419   else if (IS_PTR (type2))
1420     rType = copyLinkChain (type2);
1421   else if (getSize (type1) > getSize (type2))
1422     rType = copyLinkChain (type1);
1423   else
1424     rType = copyLinkChain (type2);
1425
1426   reType = getSpec (rType);
1427
1428   /* if either of them unsigned but not val then make this unsigned */
1429   if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) || 
1430        (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) && 
1431       !IS_FLOAT (reType))
1432     SPEC_USIGN (reType) = 1;
1433   else
1434     SPEC_USIGN (reType) = 0;
1435   
1436   /* if result is a literal then make not so */
1437   if (IS_LITERAL (reType))
1438     SPEC_SCLS (reType) = S_REGISTER;
1439
1440   return rType;
1441 }
1442
1443 /*--------------------------------------------------------------------*/
1444 /* compareType - will do type check return 1 if match, -1 if castable */
1445 /*--------------------------------------------------------------------*/
1446 int 
1447 compareType (sym_link * dest, sym_link * src)
1448 {
1449   if (!dest && !src)
1450     return 1;
1451
1452   if (dest && !src)
1453     return 0;
1454
1455   if (src && !dest)
1456     return 0;
1457
1458   /* if dest is a declarator then */
1459   if (IS_DECL (dest))
1460     {
1461       if (IS_DECL (src))
1462         {
1463           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1464             if (IS_FUNC(src)) {
1465               //checkFunction(src,dest);
1466             }
1467             return compareType (dest->next, src->next);
1468           }
1469           if (IS_PTR (src) && IS_GENPTR (dest))
1470             return -1;
1471           if (IS_PTR (dest) && IS_ARRAY (src)) {
1472             value *val=aggregateToPointer (valFromType(src));
1473             int res=compareType (dest, val->type);
1474             Safe_free(val->type);
1475             Safe_free(val);
1476             //return res ? -1 : 0;
1477             return res;
1478           }
1479           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1480             return compareType (dest->next, src);
1481           return 0;
1482         }
1483       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1484         return -1;
1485       else
1486         return 0;
1487     }
1488
1489   /* if one is a specifier and the other is not */
1490   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1491       (IS_SPEC (dest) && !IS_SPEC (src)))
1492     return 0;
1493
1494   /* if one of them is a void then ok */
1495   if (SPEC_NOUN (dest) == V_VOID &&
1496       SPEC_NOUN (src) != V_VOID)
1497     return -1;
1498
1499   if (SPEC_NOUN (dest) != V_VOID &&
1500       SPEC_NOUN (src) == V_VOID)
1501     return -1;
1502
1503   /* if they are both bitfields then if the lengths
1504      and starts don't match */
1505   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1506       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1507        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1508     return -1;
1509
1510   /* it is a specifier */
1511   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1512     {
1513       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1514           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1515           getSize (dest) == getSize (src))
1516         return 1;
1517       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1518         return -1;
1519       else
1520         return 0;
1521     }
1522   else if (IS_STRUCT (dest))
1523     {
1524       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1525         return 0;
1526       else
1527         return 1;
1528     }
1529   if (SPEC_LONG (dest) != SPEC_LONG (src))
1530     return -1;
1531
1532   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1533     return -1;
1534
1535   return 1;
1536 }
1537
1538 /*------------------------------------------------------------------*/
1539 /* inCalleeSaveList - return 1 if found in callee save list          */
1540 /*------------------------------------------------------------------*/
1541 bool 
1542 inCalleeSaveList (char *s)
1543 {
1544   int i;
1545
1546   for (i = 0; options.calleeSaves[i]; i++)
1547     if (strcmp (options.calleeSaves[i], s) == 0)
1548       return 1;
1549
1550   return 0;
1551 }
1552
1553 /*-----------------------------------------------------------------*/
1554 /* aggregateToPointer:  change an agggregate type function      */
1555 /*         argument to a pointer to that type.     */
1556 /*-----------------------------------------------------------------*/
1557 value *
1558 aggregateToPointer (value * val)
1559 {
1560   if (IS_AGGREGATE (val->type))
1561     {
1562       /* if this is a structure */
1563       /* then we need to add a new link */
1564       if (IS_STRUCT (val->type))
1565         {
1566           /* first lets add DECLARATOR type */
1567           sym_link *p = val->type;
1568
1569           werror (W_STRUCT_AS_ARG, val->name);
1570           val->type = newLink ();
1571           val->type->next = p;
1572         }
1573
1574       /* change to a pointer depending on the */
1575       /* storage class specified        */
1576       switch (SPEC_SCLS (val->etype))
1577         {
1578         case S_IDATA:
1579           DCL_TYPE (val->type) = IPOINTER;
1580           break;
1581         case S_PDATA:
1582           DCL_TYPE (val->type) = PPOINTER;
1583           break;
1584         case S_FIXED:
1585           if (SPEC_OCLS(val->etype)) {
1586             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1587             break;
1588           }
1589
1590           if (TARGET_IS_DS390)
1591             {
1592               /* The AUTO and REGISTER classes should probably
1593                * also become generic pointers, but I haven't yet
1594                * devised a test case for that.
1595                */
1596               DCL_TYPE (val->type) = GPOINTER;
1597               break;
1598             }
1599           if (options.model==MODEL_LARGE) {
1600             DCL_TYPE (val->type) = FPOINTER;
1601             break;
1602           }
1603           /* fall through! */
1604         case S_AUTO:
1605         case S_DATA:
1606         case S_REGISTER:
1607           DCL_TYPE (val->type) = POINTER;
1608           break;
1609         case S_CODE:
1610           DCL_TYPE (val->type) = CPOINTER;
1611           break;
1612         case S_XDATA:
1613           DCL_TYPE (val->type) = FPOINTER;
1614           break;
1615         case S_EEPROM:
1616           DCL_TYPE (val->type) = EEPPOINTER;
1617           break;
1618         default:
1619           DCL_TYPE (val->type) = GPOINTER;
1620         }
1621       
1622       /* is there is a symbol associated then */
1623       /* change the type of the symbol as well */
1624       if (val->sym)
1625         {
1626           val->sym->type = copyLinkChain (val->type);
1627           val->sym->etype = getSpec (val->sym->type);
1628         }
1629     }
1630   return val;
1631 }
1632 /*------------------------------------------------------------------*/
1633 /* checkFunction - does all kinds of check on a function            */
1634 /*------------------------------------------------------------------*/
1635 int 
1636 checkFunction (symbol * sym, symbol *csym)
1637 {
1638   value *exargs, *acargs;
1639   value *checkValue;
1640   int argCnt = 0;
1641
1642   if (getenv("DEBUG_SANITY")) {
1643     fprintf (stderr, "checkFunction: %s ", sym->name);
1644   }
1645
1646   /* make sure the type is complete and sane */
1647   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1648
1649   /* if not type then some kind of error */
1650   if (!sym->type)
1651     return 0;
1652
1653   /* if the function has no type then make it return int */
1654   if (!sym->type->next)
1655     sym->type->next = sym->etype = newIntLink ();
1656
1657   /* function cannot return aggregate */
1658   if (IS_AGGREGATE (sym->type->next))
1659     {
1660       werror (E_FUNC_AGGR, sym->name);
1661       return 0;
1662     }
1663
1664   /* function cannot return bit */
1665   if (IS_BITVAR (sym->type->next))
1666     {
1667       werror (E_FUNC_BIT, sym->name);
1668       return 0;
1669     }
1670
1671   /* check if this function is defined as calleeSaves
1672      then mark it as such */
1673     FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1674
1675   /* if interrupt service routine  */
1676   /* then it cannot have arguments */
1677   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1678     {
1679       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1680         werror (E_INT_ARGS, sym->name);
1681         FUNC_ARGS(sym->type)=NULL;
1682       }
1683     }
1684
1685   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1686     return 1;                   /* not defined nothing more to check  */
1687
1688   /* check if body already present */
1689   if (csym && IFFUNC_HASBODY(csym->type))
1690     {
1691       werror (E_FUNC_BODY, sym->name);
1692       return 0;
1693     }
1694
1695   /* check the return value type   */
1696   if (compareType (csym->type, sym->type) <= 0)
1697     {
1698       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1699       printFromToType(csym->type, sym->type);
1700       return 0;
1701     }
1702
1703   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1704     {
1705       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1706     }
1707
1708   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1709     {
1710       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1711     }
1712
1713   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1714     {
1715       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1716     }
1717
1718   /* compare expected args with actual args */
1719   exargs = FUNC_ARGS(csym->type);
1720   acargs = FUNC_ARGS(sym->type);
1721
1722   /* for all the expected args do */
1723   for (argCnt = 1;
1724        exargs && acargs;
1725        exargs = exargs->next, acargs = acargs->next, argCnt++)
1726     {
1727       if (getenv("DEBUG_SANITY")) {
1728         fprintf (stderr, "checkFunction: %s ", exargs->name);
1729       }
1730       /* make sure the type is complete and sane */
1731       checkTypeSanity(exargs->etype, exargs->name);
1732
1733       /* If the actual argument is an array, any prototype
1734        * will have modified it to a pointer. Duplicate that
1735        * change here.
1736        */
1737       if (IS_AGGREGATE (acargs->type))
1738         {
1739           checkValue = copyValue (acargs);
1740           aggregateToPointer (checkValue);
1741         }
1742       else
1743         {
1744           checkValue = acargs;
1745         }
1746
1747       if (compareType (exargs->type, checkValue->type) <= 0)
1748         {
1749           werror (E_ARG_TYPE, argCnt);
1750           printFromToType(exargs->type, checkValue->type);
1751           return 0;
1752         }
1753     }
1754
1755   /* if one them ended we have a problem */
1756   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1757       (!exargs && acargs && !IS_VOID (acargs->type)))
1758     werror (E_ARG_COUNT);
1759
1760   /* replace with this defition */
1761   sym->cdef = csym->cdef;
1762   deleteSym (SymbolTab, csym, csym->name);
1763   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1764   if (IS_EXTERN (csym->etype) && !
1765       IS_EXTERN (sym->etype))
1766     {
1767       addSet (&publics, sym);
1768     }
1769   return 1;
1770 }
1771
1772 /*-----------------------------------------------------------------*/
1773 /* processFuncArgs - does some processing with function args       */
1774 /*-----------------------------------------------------------------*/
1775 void 
1776 processFuncArgs (symbol * func)
1777 {
1778   value *val;
1779   int pNum = 1;
1780   sym_link *funcType=func->type;
1781
1782   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1783     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1784
1785   // if this is a pointer to a function
1786   if (IS_PTR(funcType)) {
1787     funcType=funcType->next;
1788   }
1789
1790   /* if this function has variable argument list */
1791   /* then make the function a reentrant one    */
1792   if (IFFUNC_HASVARARGS(funcType))
1793     FUNC_ISREENT(funcType)=1;
1794
1795   /* check if this function is defined as calleeSaves
1796      then mark it as such */
1797   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1798
1799   /* loop thru all the arguments   */
1800   val = FUNC_ARGS(funcType);
1801
1802   /* if it is void then remove parameters */
1803   if (val && IS_VOID (val->type))
1804     {
1805       FUNC_ARGS(funcType) = NULL;
1806       return;
1807     }
1808
1809   /* reset regparm for the port */
1810   (*port->reset_regparms) ();
1811   /* if any of the arguments is an aggregate */
1812   /* change it to pointer to the same type */
1813   while (val)
1814     {
1815       /* mark it as a register parameter if
1816          the function does not have VA_ARG
1817          and as port dictates */
1818       if (!IFFUNC_HASVARARGS(funcType) &&
1819           (*port->reg_parm) (val->type))
1820         {
1821           SPEC_REGPARM (val->etype) = 1;
1822         }
1823
1824       if (IS_AGGREGATE (val->type))
1825         {
1826           aggregateToPointer (val);
1827         }
1828
1829       val = val->next;
1830       pNum++;
1831     }
1832
1833   /* if this is an internal generated function call */
1834   if (func->cdef) {
1835     /* ignore --stack-auto for this one, we don't know how it is compiled */
1836     /* simply trust on --int-long-reent or --float-reent */
1837     if (IFFUNC_ISREENT(funcType)) {
1838       return;
1839     }
1840   } else {
1841     /* if this function is reentrant or */
1842     /* automatics r 2b stacked then nothing */
1843     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1844       return;
1845   }
1846
1847   val = FUNC_ARGS(funcType);
1848   pNum = 1;
1849   while (val)
1850     {
1851
1852       /* if a symbolname is not given  */
1853       /* synthesize a variable name */
1854       if (!val->sym)
1855         {
1856
1857           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1858           val->sym = newSymbol (val->name, 1);
1859           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1860           val->sym->type = copyLinkChain (val->type);
1861           val->sym->etype = getSpec (val->sym->type);
1862           val->sym->_isparm = 1;
1863           strcpy (val->sym->rname, val->name);
1864           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1865             SPEC_STAT (func->etype);
1866           addSymChain (val->sym);
1867
1868         }
1869       else                      /* symbol name given create synth name */
1870         {
1871
1872           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1873           strcpy (val->sym->rname, val->name);
1874           val->sym->_isparm = 1;
1875           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1876             (options.model != MODEL_SMALL ? xdata : data);
1877           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1878             SPEC_STAT (func->etype);
1879         }
1880       val = val->next;
1881     }
1882 }
1883
1884 /*-----------------------------------------------------------------*/
1885 /* isSymbolEqual - compares two symbols return 1 if they match     */
1886 /*-----------------------------------------------------------------*/
1887 int 
1888 isSymbolEqual (symbol * dest, symbol * src)
1889 {
1890   /* if pointers match then equal */
1891   if (dest == src)
1892     return 1;
1893
1894   /* if one of them is null then don't match */
1895   if (!dest || !src)
1896     return 0;
1897
1898   /* if both of them have rname match on rname */
1899   if (dest->rname[0] && src->rname[0])
1900     return (!strcmp (dest->rname, src->rname));
1901
1902   /* otherwise match on name */
1903   return (!strcmp (dest->name, src->name));
1904 }
1905
1906 void PT(sym_link *type)
1907 {
1908         printTypeChain(type,0);
1909 }
1910 /*-----------------------------------------------------------------*/
1911 /* printTypeChain - prints the type chain in human readable form   */
1912 /*-----------------------------------------------------------------*/
1913 void
1914 printTypeChain (sym_link * start, FILE * of)
1915 {
1916   int nlr = 0;
1917   sym_link * type, * search;
1918
1919   if (!of)
1920     {
1921       of = stdout;
1922       nlr = 1;
1923     }
1924
1925   if (start==NULL) {
1926     fprintf (of, "void");
1927     return;
1928   }
1929
1930   /* print the chain as it is written in the source: */
1931   /* start with the last entry                       */
1932   for (type = start; type && type->next; type = type->next)
1933     ;
1934   while (type)
1935     {
1936       if (IS_DECL (type))
1937         {
1938           if (DCL_PTR_VOLATILE (type)) {
1939             fprintf (of, "volatile ");
1940           }
1941           switch (DCL_TYPE (type))
1942             {
1943             case FUNCTION:
1944               fprintf (of, "function ");
1945               break;
1946             case GPOINTER:
1947               if (DCL_PTR_CONST (type))
1948                 fprintf (of, "const ");
1949               fprintf (of, "generic * ");
1950               break;
1951             case CPOINTER:
1952               if (DCL_PTR_CONST (type))
1953                 fprintf (of, "const ");
1954               fprintf (of, "code * ");
1955               break;
1956             case FPOINTER:
1957               if (DCL_PTR_CONST (type))
1958                 fprintf (of, "const ");
1959               fprintf (of, "xdata * ");
1960               break;
1961             case EEPPOINTER:
1962               if (DCL_PTR_CONST (type))
1963                 fprintf (of, "const ");
1964               fprintf (of, "eeprom * ");
1965               break;
1966
1967             case POINTER:
1968               if (DCL_PTR_CONST (type))
1969                 fprintf (of, "const ");
1970               fprintf (of, "near *");
1971               break;
1972             case IPOINTER:
1973               if (DCL_PTR_CONST (type))
1974                 fprintf (of, "const ");
1975               fprintf (of, "idata * ");
1976               break;
1977             case PPOINTER:
1978               if (DCL_PTR_CONST (type))
1979                 fprintf (of, "const ");
1980               fprintf (of, "pdata * ");
1981               break;
1982             case UPOINTER:
1983               if (DCL_PTR_CONST (type))
1984                 fprintf (of, "const ");
1985               fprintf (of, "unkown * ");
1986               break;
1987             case ARRAY:
1988               fprintf (of, "[] ");
1989               break;
1990             }
1991         }
1992       else
1993         {
1994           switch (SPEC_SCLS(type)) 
1995             {
1996             case S_DATA: fprintf (of, "data "); break;
1997             case S_XDATA: fprintf (of, "xdata "); break;
1998             case S_SFR: fprintf (of, "sfr "); break;
1999             case S_SBIT: fprintf (of, "sbit "); break;
2000             case S_CODE: fprintf (of, "code "); break;
2001             case S_IDATA: fprintf (of, "idata "); break;
2002             case S_PDATA: fprintf (of, "pdata "); break;
2003             case S_LITERAL: fprintf (of, "literal "); break;
2004             case S_STACK: fprintf (of, "stack "); break;
2005             case S_XSTACK: fprintf (of, "xstack "); break;
2006             case S_BIT: fprintf (of, "bit "); break;
2007             case S_EEPROM: fprintf (of, "eeprom "); break;
2008             default: break;
2009             }
2010
2011           if (SPEC_VOLATILE (type))
2012             fprintf (of, "volatile ");
2013           if (SPEC_USIGN (type))
2014             fprintf (of, "unsigned ");
2015           if (SPEC_CONST (type))
2016             fprintf (of, "const ");
2017
2018           switch (SPEC_NOUN (type))
2019             {
2020             case V_INT:
2021               if (IS_LONG (type))
2022                 fprintf (of, "long ");
2023               fprintf (of, "int");
2024               break;
2025
2026             case V_CHAR:
2027               fprintf (of, "char");
2028               break;
2029
2030             case V_VOID:
2031               fprintf (of, "void");
2032               break;
2033
2034             case V_FLOAT:
2035               fprintf (of, "float");
2036               break;
2037
2038             case V_STRUCT:
2039               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2040               break;
2041
2042             case V_SBIT:
2043               fprintf (of, "sbit");
2044               break;
2045
2046             case V_BIT:
2047               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2048               break;
2049
2050             case V_DOUBLE:
2051               fprintf (of, "double");
2052               break;
2053
2054             default:
2055               fprintf (of, "unknown type");
2056               break;
2057             }
2058         }
2059         /* search entry in list before "type" */
2060     for (search = start; search && search->next != type;)
2061        search = search->next;
2062     type = search;
2063     if (type)
2064       fputc (' ', of);
2065     }
2066   if (nlr)
2067     fprintf (of, "\n");
2068 }
2069
2070 /*-----------------------------------------------------------------*/
2071 /* cdbTypeInfo - print the type information for debugger           */
2072 /*-----------------------------------------------------------------*/
2073 void
2074 cdbTypeInfo (sym_link * type, FILE * of)
2075 {
2076   fprintf (of, "{%d}", getSize (type));
2077   while (type)
2078     {
2079       if (IS_DECL (type))
2080         {
2081           switch (DCL_TYPE (type))
2082             {
2083             case FUNCTION:
2084               fprintf (of, "DF,");
2085               break;
2086             case GPOINTER:
2087               fprintf (of, "DG,");
2088               break;
2089             case CPOINTER:
2090               fprintf (of, "DC,");
2091               break;
2092             case FPOINTER:
2093               fprintf (of, "DX,");
2094               break;
2095             case POINTER:
2096               fprintf (of, "DD,");
2097               break;
2098             case IPOINTER:
2099               fprintf (of, "DI,");
2100               break;
2101             case PPOINTER:
2102               fprintf (of, "DP,");
2103               break;
2104             case EEPPOINTER:
2105               fprintf (of, "DA,");
2106               break;
2107             case ARRAY:
2108               fprintf (of, "DA%d,", DCL_ELEM (type));
2109               break;
2110             default:
2111               break;
2112             }
2113         }
2114       else
2115         {
2116           switch (SPEC_NOUN (type))
2117             {
2118             case V_INT:
2119               if (IS_LONG (type))
2120                 fprintf (of, "SL");
2121               else
2122                 fprintf (of, "SI");
2123               break;
2124
2125             case V_CHAR:
2126               fprintf (of, "SC");
2127               break;
2128
2129             case V_VOID:
2130               fprintf (of, "SV");
2131               break;
2132
2133             case V_FLOAT:
2134               fprintf (of, "SF");
2135               break;
2136
2137             case V_STRUCT:
2138               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2139               break;
2140
2141             case V_SBIT:
2142               fprintf (of, "SX");
2143               break;
2144
2145             case V_BIT:
2146               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2147               break;
2148
2149             default:
2150               break;
2151             }
2152           fputs (":", of);
2153           if (SPEC_USIGN (type))
2154             fputs ("U", of);
2155           else
2156             fputs ("S", of);
2157         }
2158       type = type->next;
2159     }
2160 }
2161 /*-----------------------------------------------------------------*/
2162 /* cdbSymbol - prints a symbol & its type information for debugger */
2163 /*-----------------------------------------------------------------*/
2164 void 
2165 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2166 {
2167   memmap *map;
2168
2169   if (!sym)
2170     return;
2171   if (!of)
2172     of = stdout;
2173
2174   if (isFunc)
2175     fprintf (of, "F:");
2176   else
2177     fprintf (of, "S:");         /* symbol record */
2178   /* if this is not a structure symbol then
2179      we need to figure out the scope information */
2180   if (!isStructSym)
2181     {
2182       if (!sym->level)
2183         {
2184           /* global */
2185           if (IS_STATIC (sym->etype))
2186             fprintf (of, "F%s$", moduleName);   /* scope is file */
2187           else
2188             fprintf (of, "G$"); /* scope is global */
2189         }
2190       else
2191         /* symbol is local */
2192         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2193     }
2194   else
2195     fprintf (of, "S$");         /* scope is structure */
2196
2197   /* print the name, & mangled name */
2198   fprintf (of, "%s$%d$%d(", sym->name,
2199            sym->level, sym->block);
2200
2201   cdbTypeInfo (sym->type, of);
2202   fprintf (of, "),");
2203
2204   /* print the address space */
2205   map = SPEC_OCLS (sym->etype);
2206   fprintf (of, "%c,%d,%d",
2207            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2208
2209   /* if assigned to registers then output register names */
2210   /* if this is a function then print
2211      if is it an interrupt routine & interrupt number
2212      and the register bank it is using */
2213   if (isFunc)
2214     fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
2215              FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
2216   /* alternate location to find this symbol @ : eg registers
2217      or spillication */
2218
2219   if (!isStructSym)
2220     fprintf (of, "\n");
2221 }
2222
2223 /*-----------------------------------------------------------------*/
2224 /* cdbStruct - print a structure for debugger                      */
2225 /*-----------------------------------------------------------------*/
2226 void 
2227 cdbStruct (structdef * sdef, int block, FILE * of,
2228            int inStruct, char *tag)
2229 {
2230   symbol *sym;
2231
2232   fprintf (of, "T:");
2233   /* if block # then must have function scope */
2234   fprintf (of, "F%s$", moduleName);
2235   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2236   for (sym = sdef->fields; sym; sym = sym->next)
2237     {
2238       fprintf (of, "({%d}", sym->offset);
2239       cdbSymbol (sym, of, TRUE, FALSE);
2240       fprintf (of, ")");
2241     }
2242   fprintf (of, "]");
2243   if (!inStruct)
2244     fprintf (of, "\n");
2245 }
2246
2247 /*------------------------------------------------------------------*/
2248 /* cdbStructBlock - calls struct printing for a blcks               */
2249 /*------------------------------------------------------------------*/
2250 void 
2251 cdbStructBlock (int block, FILE * of)
2252 {
2253   int i;
2254   bucket **table = StructTab;
2255   bucket *chain;
2256   wassert (of);
2257
2258   /* go thru the entire  table  */
2259   for (i = 0; i < 256; i++)
2260     {
2261       for (chain = table[i]; chain; chain = chain->next)
2262         {
2263           if (chain->block >= block)
2264             {
2265               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2266             }
2267         }
2268     }
2269 }
2270
2271 /*-----------------------------------------------------------------*/
2272 /* powof2 - returns power of two for the number if number is pow 2 */
2273 /*-----------------------------------------------------------------*/
2274 int 
2275 powof2 (unsigned long num)
2276 {
2277   int nshifts = 0;
2278   int n1s = 0;
2279
2280   while (num)
2281     {
2282       if (num & 1)
2283         n1s++;
2284       num >>= 1;
2285       nshifts++;
2286     }
2287
2288   if (n1s > 1 || nshifts == 0)
2289     return 0;
2290   return nshifts - 1;
2291 }
2292
2293 symbol *__fsadd;
2294 symbol *__fssub;
2295 symbol *__fsmul;
2296 symbol *__fsdiv;
2297 symbol *__fseq;
2298 symbol *__fsneq;
2299 symbol *__fslt;
2300 symbol *__fslteq;
2301 symbol *__fsgt;
2302 symbol *__fsgteq;
2303
2304 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2305 symbol *__muldiv[3][3][2];
2306 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2307 sym_link *__multypes[3][2];
2308 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2309 symbol *__conv[2][3][2];
2310 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2311 symbol *__rlrr[2][3][2];
2312
2313 sym_link *floatType;
2314
2315 static char *
2316 _mangleFunctionName(char *in)
2317 {
2318   if (port->getMangledFunctionName) 
2319     {
2320       return port->getMangledFunctionName(in);
2321     }
2322   else
2323     {
2324       return in;
2325     }
2326 }
2327
2328 /*-----------------------------------------------------------------*/
2329 /* initCSupport - create functions for C support routines          */
2330 /*-----------------------------------------------------------------*/
2331 void 
2332 initCSupport ()
2333 {
2334   const char *smuldivmod[] =
2335   {
2336     "mul", "div", "mod"
2337   };
2338   const char *sbwd[] =
2339   {
2340     "char", "int", "long"
2341   };
2342   const char *ssu[] =
2343   {
2344     "s", "u"
2345   };
2346   const char *srlrr[] =
2347   {
2348     "rl", "rr"
2349   };
2350
2351   int bwd, su, muldivmod, tofrom, rlrr;
2352
2353   if (getenv("SDCC_NO_C_SUPPORT")) {
2354     /* for debugging only */
2355     return;
2356   }
2357
2358   floatType = newFloatLink ();
2359
2360   for (bwd = 0; bwd < 3; bwd++)
2361     {
2362       sym_link *l;
2363       switch (bwd)
2364         {
2365         case 0:
2366           l = newCharLink ();
2367           break;
2368         case 1:
2369           l = newIntLink ();
2370           break;
2371         case 2:
2372           l = newLongLink ();
2373           break;
2374         default:
2375           assert (0);
2376         }
2377       __multypes[bwd][0] = l;
2378       __multypes[bwd][1] = copyLinkChain (l);
2379       SPEC_USIGN (__multypes[bwd][1]) = 1;
2380     }
2381
2382   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2383   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2384   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2385   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2386   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2387   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2388   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2389   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2390   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2391   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2392
2393   for (tofrom = 0; tofrom < 2; tofrom++)
2394     {
2395       for (bwd = 0; bwd < 3; bwd++)
2396         {
2397           for (su = 0; su < 2; su++)
2398             {
2399               if (tofrom)
2400                 {
2401                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2402                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
2403                 }
2404               else
2405                 {
2406                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2407                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
2408                 }
2409             }
2410         }
2411     }
2412
2413   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2414     {
2415       for (bwd = 0; bwd < 3; bwd++)
2416         {
2417           for (su = 0; su < 2; su++)
2418             {
2419               sprintf (buffer, "_%s%s%s",
2420                        smuldivmod[muldivmod],
2421                        ssu[su],
2422                        sbwd[bwd]);
2423               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2424               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2425             }
2426         }
2427     }
2428
2429   for (rlrr = 0; rlrr < 2; rlrr++)
2430     {
2431       for (bwd = 0; bwd < 3; bwd++)
2432         {
2433           for (su = 0; su < 2; su++)
2434             {
2435               sprintf (buffer, "_%s%s%s",
2436                        srlrr[rlrr],
2437                        ssu[su],
2438                        sbwd[bwd]);
2439               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2440               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2441             }
2442         }
2443     }
2444 }