size of a function is the size of a code pointer
[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 ARRAY:
786       return DCL_ELEM (p) * getSize (p->next);
787     case IPOINTER:
788     case PPOINTER:
789     case POINTER:
790       return (PTRSIZE);
791     case EEPPOINTER:
792     case FPOINTER:
793     case CPOINTER:
794     case FUNCTION:
795       return (FPTRSIZE);
796     case GPOINTER:
797       return (GPTRSIZE);
798
799     default:
800       return 0;
801     }
802 }
803
804 /*------------------------------------------------------------------*/
805 /* bitsForType - returns # of bits required to store this type      */
806 /*------------------------------------------------------------------*/
807 unsigned int 
808 bitsForType (sym_link * p)
809 {
810   /* if nothing return 0 */
811   if (!p)
812     return 0;
813
814   if (IS_SPEC (p))
815     {                           /* if this is the specifier then */
816
817       switch (SPEC_NOUN (p))
818         {                       /* depending on the specifier type */
819         case V_INT:
820           return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
821         case V_FLOAT:
822           return FLOATSIZE * 8;
823         case V_CHAR:
824           return CHARSIZE * 8;
825         case V_VOID:
826           return 0;
827         case V_STRUCT:
828           return SPEC_STRUCT (p)->size * 8;
829         case V_LABEL:
830           return 0;
831         case V_SBIT:
832           return 1;
833         case V_BIT:
834           return SPEC_BLEN (p);
835         default:
836           return 0;
837         }
838     }
839
840   /* this is a specifier  */
841   switch (DCL_TYPE (p))
842     {
843     case ARRAY:
844       return DCL_ELEM (p) * getSize (p->next) * 8;
845     case IPOINTER:
846     case PPOINTER:
847     case POINTER:
848       return (PTRSIZE * 8);
849     case EEPPOINTER:
850     case FPOINTER:
851     case CPOINTER:
852     case FUNCTION:
853       return (FPTRSIZE * 8);
854     case GPOINTER:
855       return (GPTRSIZE * 8);
856
857     default:
858       return 0;
859     }
860 }
861
862 /*------------------------------------------------------------------*/
863 /* copySymbolChain - copies a symbol chain                          */
864 /*------------------------------------------------------------------*/
865 symbol *
866 copySymbolChain (symbol * src)
867 {
868   symbol *dest;
869
870   if (!src)
871     return NULL;
872
873   dest = copySymbol (src);
874   dest->next = copySymbolChain (src->next);
875   return dest;
876 }
877
878 /*------------------------------------------------------------------*/
879 /* copySymbol - makes a copy of a symbol                            */
880 /*------------------------------------------------------------------*/
881 symbol *
882 copySymbol (symbol * src)
883 {
884   symbol *dest;
885
886   if (!src)
887     return NULL;
888
889   dest = newSymbol (src->name, src->level);
890   memcpy (dest, src, sizeof (symbol));
891   dest->level = src->level;
892   dest->block = src->block;
893   dest->ival = copyIlist (src->ival);
894   dest->type = copyLinkChain (src->type);
895   dest->etype = getSpec (dest->type);
896   dest->next = NULL;
897   dest->key = src->key;
898   dest->allocreq = src->allocreq;
899   return dest;
900 }
901
902 /*------------------------------------------------------------------*/
903 /* reverseSyms - reverses the links for a symbol chain      */
904 /*------------------------------------------------------------------*/
905 symbol *
906 reverseSyms (symbol * sym)
907 {
908   symbol *prev, *curr, *next;
909
910   if (!sym)
911     return NULL;
912
913   prev = sym;
914   curr = sym->next;
915
916   while (curr)
917     {
918       next = curr->next;
919       curr->next = prev;
920       prev = curr;
921       curr = next;
922     }
923   sym->next = (void *) NULL;
924   return prev;
925 }
926
927 /*------------------------------------------------------------------*/
928 /* reverseLink - reverses the links for a type chain        */
929 /*------------------------------------------------------------------*/
930 sym_link *
931 reverseLink (sym_link * type)
932 {
933   sym_link *prev, *curr, *next;
934
935   if (!type)
936     return NULL;
937
938   prev = type;
939   curr = type->next;
940
941   while (curr)
942     {
943       next = curr->next;
944       curr->next = prev;
945       prev = curr;
946       curr = next;
947     }
948   type->next = (void *) NULL;
949   return prev;
950 }
951
952 /*------------------------------------------------------------------*/
953 /* addSymChain - adds a symbol chain to the symboltable             */
954 /*------------------------------------------------------------------*/
955 void 
956 addSymChain (symbol * symHead)
957 {
958   symbol *sym = symHead;
959   symbol *csym = NULL;
960
961   for (; sym != NULL; sym = sym->next)
962     {
963       changePointer(sym);
964       checkTypeSanity(sym->etype, sym->name);
965
966       /* if already exists in the symbol table then check if
967          one of them is an extern definition if yes then
968          then check if the type match, if the types match then
969          delete the current entry and add the new entry      */
970       if ((csym = findSymWithLevel (SymbolTab, sym)) &&
971           csym->level == sym->level) {
972         
973         /* one definition extern ? */
974         if (IS_EXTERN (csym->etype) || IS_EXTERN (sym->etype)) {
975           /* do types match ? */
976           if (compareType (csym->type, sym->type) != 1) {
977             /* no then error */
978             werror (E_EXTERN_MISMATCH, csym->name);
979             continue;
980           }
981           /* delete current entry */
982           deleteSym (SymbolTab, csym, csym->name);
983         } else {
984           /* not extern */
985           werror (E_DUPLICATE, sym->name);
986           continue;
987         }
988       }
989
990       /* add new entry */
991       addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
992     }
993 }
994
995
996 /*------------------------------------------------------------------*/
997 /* funcInChain - DCL Type 'FUNCTION' found in type chain            */
998 /*------------------------------------------------------------------*/
999 int 
1000 funcInChain (sym_link * lnk)
1001 {
1002   while (lnk)
1003     {
1004       if (IS_FUNC (lnk))
1005         return 1;
1006       lnk = lnk->next;
1007     }
1008   return 0;
1009 }
1010
1011 /*------------------------------------------------------------------*/
1012 /* structElemType - returns the type info of a sturct member        */
1013 /*------------------------------------------------------------------*/
1014 sym_link *
1015 structElemType (sym_link * stype, value * id)
1016 {
1017   symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
1018   sym_link *type, *etype;
1019   sym_link *petype = getSpec (stype);
1020
1021   if (!fields || !id)
1022     return NULL;
1023
1024   /* look for the id */
1025   while (fields)
1026     {
1027       if (strcmp (fields->rname, id->name) == 0)
1028         {
1029           type = copyLinkChain (fields->type);
1030           etype = getSpec (type);
1031           SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
1032                                SPEC_SCLS (etype) : SPEC_SCLS (petype));
1033           return type;
1034         }
1035       fields = fields->next;
1036     }
1037   werror (E_NOT_MEMBER, id->name);
1038
1039   return NULL;
1040 }
1041
1042 /*------------------------------------------------------------------*/
1043 /* getStructElement - returns element of a tructure definition      */
1044 /*------------------------------------------------------------------*/
1045 symbol *
1046 getStructElement (structdef * sdef, symbol * sym)
1047 {
1048   symbol *field;
1049
1050   for (field = sdef->fields; field; field = field->next)
1051     if (strcmp (field->name, sym->name) == 0)
1052       return field;
1053
1054   werror (E_NOT_MEMBER, sym->name);
1055
1056   return sdef->fields;
1057 }
1058
1059 /*------------------------------------------------------------------*/
1060 /* compStructSize - computes the size of a structure                */
1061 /*------------------------------------------------------------------*/
1062 int 
1063 compStructSize (int su, structdef * sdef)
1064 {
1065     int sum = 0, usum = 0;
1066     int bitOffset = 0;
1067     symbol *loop;
1068
1069     /* for the identifiers  */
1070     loop = sdef->fields;
1071     while (loop) {
1072
1073         /* create the internal name for this variable */
1074         sprintf (loop->rname, "_%s", loop->name);
1075         loop->offset = (su == UNION ? sum = 0 : sum);
1076         SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
1077
1078         /* if this is a bit field  */
1079         if (loop->bitVar) {
1080
1081             /* change it to a unsigned bit */
1082             SPEC_NOUN (loop->etype) = V_BIT;
1083             SPEC_USIGN (loop->etype) = 1;
1084             /* check if this fit into the remaining   */
1085             /* bits of this byte else align it to the */
1086             /* next byte boundary                     */
1087             if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
1088                 SPEC_BSTR (loop->etype) = bitOffset;
1089                 if ((bitOffset += (loop->bitVar % 8)) == 8)
1090                     sum++;
1091             }
1092             else /* does not fit */ {
1093                 bitOffset = 0;
1094                 SPEC_BSTR (loop->etype) = bitOffset;
1095                 sum += (loop->bitVar / 8);
1096                 bitOffset += (loop->bitVar % 8);
1097             }
1098             /* if this is the last field then pad */
1099             if (!loop->next && bitOffset && bitOffset != 8) {
1100                 bitOffset = 0;
1101                 sum++;
1102             }
1103         }
1104         else {
1105             checkDecl (loop, 1);
1106             sum += getSize (loop->type);
1107         }
1108
1109 #if 0 // jwk: this is done now in addDecl()
1110         /* if function then do the arguments for it */
1111         if (funcInChain (loop->type)) {
1112             processFuncArgs (loop);
1113         }
1114 #endif
1115
1116         loop = loop->next;
1117
1118         /* if this is not a bitfield but the */
1119         /* previous one was and did not take */
1120         /* the whole byte then pad the rest  */
1121         if ((loop && !loop->bitVar) && bitOffset) {
1122             bitOffset = 0;
1123             sum++;
1124         }
1125
1126         /* if union then size = sizeof larget field */
1127         if (su == UNION)
1128             usum = max (usum, sum);
1129
1130     }
1131
1132     return (su == UNION ? usum : sum);
1133 }
1134
1135 /*------------------------------------------------------------------*/
1136 /* checkSClass - check the storage class specification              */
1137 /*------------------------------------------------------------------*/
1138 static void 
1139 checkSClass (symbol * sym, int isProto)
1140 {
1141   if (getenv("DEBUG_SANITY")) {
1142     fprintf (stderr, "checkSClass: %s \n", sym->name);
1143   }
1144   
1145   /* type is literal can happen foe enums change
1146      to auto */
1147   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1148     SPEC_SCLS (sym->etype) = S_AUTO;
1149   
1150   /* if sfr or sbit then must also be */
1151   /* volatile the initial value will be xlated */
1152   /* to an absolute address */
1153   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1154       SPEC_SCLS (sym->etype) == S_SFR)
1155     {
1156       SPEC_VOLATILE (sym->etype) = 1;
1157       /* if initial value given */
1158       if (sym->ival)
1159         {
1160           SPEC_ABSA (sym->etype) = 1;
1161           SPEC_ADDR (sym->etype) =
1162             (int) list2int (sym->ival);
1163           sym->ival = NULL;
1164         }
1165     }
1166   
1167   /* if absolute address given then it mark it as
1168      volatile */
1169   if (IS_ABSOLUTE (sym->etype))
1170     SPEC_VOLATILE (sym->etype) = 1;
1171   
1172   /* global variables declared const put into code */
1173   if (sym->level == 0 &&
1174       SPEC_CONST (sym->etype)) {
1175     SPEC_SCLS (sym->etype) = S_CODE;
1176   }
1177   
1178   /* global variable in code space is a constant */
1179   if (sym->level == 0 &&
1180       SPEC_SCLS (sym->etype) == S_CODE &&
1181       port->mem.code_ro)
1182     SPEC_CONST (sym->etype) = 1;
1183   
1184
1185   /* if bit variable then no storage class can be */
1186   /* specified since bit is already a storage */
1187   if (IS_BITVAR (sym->etype) &&
1188       (SPEC_SCLS (sym->etype) != S_FIXED &&
1189        SPEC_SCLS (sym->etype) != S_SBIT &&
1190        SPEC_SCLS (sym->etype) != S_BIT)
1191     )
1192     {
1193       werror (E_BITVAR_STORAGE, sym->name);
1194       SPEC_SCLS (sym->etype) = S_FIXED;
1195     }
1196
1197   /* extern variables cannot be initialized */
1198   if (IS_EXTERN (sym->etype) && sym->ival)
1199     {
1200       werror (E_EXTERN_INIT, sym->name);
1201       sym->ival = NULL;
1202     }
1203
1204   /* if this is an atomatic symbol */
1205   if (sym->level && (options.stackAuto || reentrant)) {
1206     if ((SPEC_SCLS (sym->etype) == S_AUTO ||
1207          SPEC_SCLS (sym->etype) == S_FIXED ||
1208          SPEC_SCLS (sym->etype) == S_REGISTER ||
1209          SPEC_SCLS (sym->etype) == S_STACK ||
1210          SPEC_SCLS (sym->etype) == S_XSTACK)) {
1211       SPEC_SCLS (sym->etype) = S_AUTO;
1212     } else {
1213       /* storage class may only be specified for statics */
1214       if (!IS_STATIC(sym->etype)) {
1215         werror (E_AUTO_ASSUMED, sym->name);
1216       }
1217     }
1218   }
1219   
1220   /* automatic symbols cannot be given   */
1221   /* an absolute address ignore it      */
1222   if (sym->level &&
1223       SPEC_ABSA (sym->etype) &&
1224       (options.stackAuto || reentrant))
1225     {
1226       werror (E_AUTO_ABSA, sym->name);
1227       SPEC_ABSA (sym->etype) = 0;
1228     }
1229
1230   /* arrays & pointers cannot be defined for bits   */
1231   /* SBITS or SFRs or BIT                           */
1232   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1233       (SPEC_NOUN (sym->etype) == V_BIT ||
1234        SPEC_NOUN (sym->etype) == V_SBIT ||
1235        SPEC_SCLS (sym->etype) == S_SFR))
1236     werror (E_BIT_ARRAY, sym->name);
1237
1238   /* if this is a bit|sbit then set length & start  */
1239   if (SPEC_NOUN (sym->etype) == V_BIT ||
1240       SPEC_NOUN (sym->etype) == V_SBIT)
1241     {
1242       SPEC_BLEN (sym->etype) = 1;
1243       SPEC_BSTR (sym->etype) = 0;
1244     }
1245
1246   if (!isProto) {
1247     /* variables declared in CODE space must have */
1248     /* initializers if not an extern */
1249     if (SPEC_SCLS (sym->etype) == S_CODE &&
1250         sym->ival == NULL &&
1251         //!sym->level &&
1252         port->mem.code_ro &&
1253         !IS_EXTERN (sym->etype) &&
1254         !funcInChain (sym->type))
1255       werror (E_CODE_NO_INIT, sym->name);
1256   }
1257
1258   /* if parameter or local variable then change */
1259   /* the storage class to reflect where the var will go */
1260   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1261       !IS_STATIC(sym->etype))
1262     {
1263       if (options.stackAuto || (currFunc && IFFUNC_ISREENT (currFunc->type)))
1264         {
1265           SPEC_SCLS (sym->etype) = (options.useXstack ?
1266                                     S_XSTACK : S_STACK);
1267         }
1268       else
1269         {
1270           /* hack-o-matic! I see no reason why the useXstack option should ever
1271            * control this allcoation, but the code was originally that way, and
1272            * changing it for non-390 ports breaks the compiler badly.
1273            */
1274           bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1275           SPEC_SCLS (sym->etype) = (useXdata ?
1276                                     S_XDATA : S_FIXED);
1277         }
1278     }
1279 }
1280
1281 /*------------------------------------------------------------------*/
1282 /* changePointer - change pointer to functions                      */
1283 /*------------------------------------------------------------------*/
1284 void 
1285 changePointer (symbol * sym)
1286 {
1287   sym_link *p;
1288
1289   /* go thru the chain of declarations   */
1290   /* if we find a pointer to a function  */
1291   /* unconditionally change it to a ptr  */
1292   /* to code area                        */
1293   for (p = sym->type; p; p = p->next)
1294     {
1295       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1296         DCL_TYPE (p) = GPOINTER;
1297       if (IS_PTR (p) && IS_FUNC (p->next))
1298         DCL_TYPE (p) = CPOINTER;
1299     }
1300 }
1301
1302 /*------------------------------------------------------------------*/
1303 /* checkDecl - does semantic validation of a declaration                   */
1304 /*------------------------------------------------------------------*/
1305 int 
1306 checkDecl (symbol * sym, int isProto)
1307 {
1308
1309   checkSClass (sym, isProto);           /* check the storage class      */
1310   changePointer (sym);          /* change pointers if required */
1311
1312   /* if this is an array without any dimension
1313      then update the dimension from the initial value */
1314   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1315     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1316
1317   return 0;
1318 }
1319
1320 /*------------------------------------------------------------------*/
1321 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1322 /*------------------------------------------------------------------*/
1323 sym_link *
1324 copyLinkChain (sym_link * p)
1325 {
1326   sym_link *head, *curr, *loop;
1327
1328   curr = p;
1329   head = loop = (curr ? newLink () : (void *) NULL);
1330   while (curr)
1331     {
1332       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1333       loop->next = (curr->next ? newLink () : (void *) NULL);
1334       loop = loop->next;
1335       curr = curr->next;
1336     }
1337
1338   return head;
1339 }
1340
1341
1342 /*------------------------------------------------------------------*/
1343 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1344 /*                symbols in the given block                        */
1345 /*------------------------------------------------------------------*/
1346 void 
1347 cleanUpBlock (bucket ** table, int block)
1348 {
1349   int i;
1350   bucket *chain;
1351
1352   /* go thru the entire  table  */
1353   for (i = 0; i < 256; i++)
1354     {
1355       for (chain = table[i]; chain; chain = chain->next)
1356         {
1357           if (chain->block >= block)
1358             {
1359               deleteSym (table, chain->sym, chain->name);
1360             }
1361         }
1362     }
1363 }
1364
1365 /*------------------------------------------------------------------*/
1366 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1367 /*                symbols in the given level                        */
1368 /*------------------------------------------------------------------*/
1369 void 
1370 cleanUpLevel (bucket ** table, int level)
1371 {
1372   int i;
1373   bucket *chain;
1374
1375   /* go thru the entire  table  */
1376   for (i = 0; i < 256; i++)
1377     {
1378       for (chain = table[i]; chain; chain = chain->next)
1379         {
1380           if (chain->level >= level)
1381             {
1382               deleteSym (table, chain->sym, chain->name);
1383             }
1384         }
1385     }
1386 }
1387
1388 /*------------------------------------------------------------------*/
1389 /* computeType - computes the resultant type from two types         */
1390 /*------------------------------------------------------------------*/
1391 sym_link *
1392 computeType (sym_link * type1, sym_link * type2)
1393 {
1394   sym_link *rType;
1395   sym_link *reType;
1396   sym_link *etype1 = getSpec (type1);
1397   sym_link *etype2 = getSpec (type2);
1398
1399   /* if one of them is a float then result is a float */
1400   /* here we assume that the types passed are okay */
1401   /* and can be cast to one another                */
1402   /* which ever is greater in size */
1403   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1404     rType = newFloatLink ();
1405   else
1406     /* if only one of them is a bit variable
1407        then the other one prevails */
1408   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1409     rType = copyLinkChain (type2);
1410   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1411     rType = copyLinkChain (type1);
1412   else
1413     /* if one of them is a pointer then that
1414        prevails */
1415   if (IS_PTR (type1))
1416     rType = copyLinkChain (type1);
1417   else if (IS_PTR (type2))
1418     rType = copyLinkChain (type2);
1419   else if (getSize (type1) > getSize (type2))
1420     rType = copyLinkChain (type1);
1421   else
1422     rType = copyLinkChain (type2);
1423
1424   reType = getSpec (rType);
1425
1426   /* if either of them unsigned but not val then make this unsigned */
1427   if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) || 
1428        (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) && 
1429       !IS_FLOAT (reType))
1430     SPEC_USIGN (reType) = 1;
1431   else
1432     SPEC_USIGN (reType) = 0;
1433   
1434   /* if result is a literal then make not so */
1435   if (IS_LITERAL (reType))
1436     SPEC_SCLS (reType) = S_REGISTER;
1437
1438   return rType;
1439 }
1440
1441 /*--------------------------------------------------------------------*/
1442 /* compareType - will do type check return 1 if match, -1 if castable */
1443 /*--------------------------------------------------------------------*/
1444 int 
1445 compareType (sym_link * dest, sym_link * src)
1446 {
1447   if (!dest && !src)
1448     return 1;
1449
1450   if (dest && !src)
1451     return 0;
1452
1453   if (src && !dest)
1454     return 0;
1455
1456   /* if dest is a declarator then */
1457   if (IS_DECL (dest))
1458     {
1459       if (IS_DECL (src))
1460         {
1461           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
1462             if (IS_FUNC(src)) {
1463               //checkFunction(src,dest);
1464             }
1465             return compareType (dest->next, src->next);
1466           }
1467           if (IS_PTR (src) && IS_GENPTR (dest))
1468             return -1;
1469           if (IS_PTR (dest) && IS_ARRAY (src)) {
1470             value *val=aggregateToPointer (valFromType(src));
1471             int res=compareType (dest, val->type);
1472             Safe_free(val->type);
1473             Safe_free(val);
1474             //return res ? -1 : 0;
1475             return res;
1476           }
1477           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1478             return compareType (dest->next, src);
1479           return 0;
1480         }
1481       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1482         return -1;
1483       else
1484         return 0;
1485     }
1486
1487   /* if one is a specifier and the other is not */
1488   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1489       (IS_SPEC (dest) && !IS_SPEC (src)))
1490     return 0;
1491
1492   /* if one of them is a void then ok */
1493   if (SPEC_NOUN (dest) == V_VOID &&
1494       SPEC_NOUN (src) != V_VOID)
1495     return -1;
1496
1497   if (SPEC_NOUN (dest) != V_VOID &&
1498       SPEC_NOUN (src) == V_VOID)
1499     return -1;
1500
1501   /* if they are both bitfields then if the lengths
1502      and starts don't match */
1503   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1504       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1505        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1506     return -1;
1507
1508   /* it is a specifier */
1509   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1510     {
1511       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1512           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1513           getSize (dest) == getSize (src))
1514         return 1;
1515       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1516         return -1;
1517       else
1518         return 0;
1519     }
1520   else if (IS_STRUCT (dest))
1521     {
1522       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1523         return 0;
1524       else
1525         return 1;
1526     }
1527   if (SPEC_LONG (dest) != SPEC_LONG (src))
1528     return -1;
1529
1530   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1531     return -1;
1532
1533   return 1;
1534 }
1535
1536 /*------------------------------------------------------------------*/
1537 /* inCalleeSaveList - return 1 if found in callee save list          */
1538 /*------------------------------------------------------------------*/
1539 bool 
1540 inCalleeSaveList (char *s)
1541 {
1542   int i;
1543
1544   for (i = 0; options.calleeSaves[i]; i++)
1545     if (strcmp (options.calleeSaves[i], s) == 0)
1546       return 1;
1547
1548   return 0;
1549 }
1550
1551 /*-----------------------------------------------------------------*/
1552 /* aggregateToPointer:  change an agggregate type function      */
1553 /*         argument to a pointer to that type.     */
1554 /*-----------------------------------------------------------------*/
1555 value *
1556 aggregateToPointer (value * val)
1557 {
1558   if (IS_AGGREGATE (val->type))
1559     {
1560       /* if this is a structure */
1561       /* then we need to add a new link */
1562       if (IS_STRUCT (val->type))
1563         {
1564           /* first lets add DECLARATOR type */
1565           sym_link *p = val->type;
1566
1567           werror (W_STRUCT_AS_ARG, val->name);
1568           val->type = newLink ();
1569           val->type->next = p;
1570         }
1571
1572       /* change to a pointer depending on the */
1573       /* storage class specified        */
1574       switch (SPEC_SCLS (val->etype))
1575         {
1576         case S_IDATA:
1577           DCL_TYPE (val->type) = IPOINTER;
1578           break;
1579         case S_PDATA:
1580           DCL_TYPE (val->type) = PPOINTER;
1581           break;
1582         case S_FIXED:
1583           if (SPEC_OCLS(val->etype)) {
1584             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1585           } else {
1586             // this should not happen
1587             fprintf (stderr, "wild guess about storage type\n");
1588             if (TARGET_IS_DS390) {
1589               /* The AUTO and REGISTER classes should probably
1590                * also become generic pointers, but I haven't yet
1591                * devised a test case for that.
1592                */
1593               DCL_TYPE (val->type) = GPOINTER;
1594               break;
1595             }
1596             if (options.model==MODEL_LARGE) {
1597               DCL_TYPE (val->type) = FPOINTER;
1598               break;
1599             }
1600           }
1601           break;
1602         case S_AUTO:
1603         case S_DATA:
1604         case S_REGISTER:
1605           DCL_TYPE (val->type) = POINTER;
1606           break;
1607         case S_CODE:
1608           DCL_TYPE (val->type) = CPOINTER;
1609           break;
1610         case S_XDATA:
1611           DCL_TYPE (val->type) = FPOINTER;
1612           break;
1613         case S_EEPROM:
1614           DCL_TYPE (val->type) = EEPPOINTER;
1615           break;
1616         default:
1617           DCL_TYPE (val->type) = GPOINTER;
1618         }
1619       
1620       /* is there is a symbol associated then */
1621       /* change the type of the symbol as well */
1622       if (val->sym)
1623         {
1624           val->sym->type = copyLinkChain (val->type);
1625           val->sym->etype = getSpec (val->sym->type);
1626         }
1627     }
1628   return val;
1629 }
1630 /*------------------------------------------------------------------*/
1631 /* checkFunction - does all kinds of check on a function            */
1632 /*------------------------------------------------------------------*/
1633 int 
1634 checkFunction (symbol * sym, symbol *csym)
1635 {
1636   value *exargs, *acargs;
1637   value *checkValue;
1638   int argCnt = 0;
1639
1640   if (getenv("DEBUG_SANITY")) {
1641     fprintf (stderr, "checkFunction: %s ", sym->name);
1642   }
1643
1644   /* make sure the type is complete and sane */
1645   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1646
1647   /* if not type then some kind of error */
1648   if (!sym->type)
1649     return 0;
1650
1651   /* if the function has no type then make it return int */
1652   if (!sym->type->next)
1653     sym->type->next = sym->etype = newIntLink ();
1654
1655   /* function cannot return aggregate */
1656   if (IS_AGGREGATE (sym->type->next))
1657     {
1658       werror (E_FUNC_AGGR, sym->name);
1659       return 0;
1660     }
1661
1662   /* function cannot return bit */
1663   if (IS_BITVAR (sym->type->next))
1664     {
1665       werror (E_FUNC_BIT, sym->name);
1666       return 0;
1667     }
1668
1669   /* check if this function is defined as calleeSaves
1670      then mark it as such */
1671     FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1672
1673   /* if interrupt service routine  */
1674   /* then it cannot have arguments */
1675   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1676     {
1677       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1678         werror (E_INT_ARGS, sym->name);
1679         FUNC_ARGS(sym->type)=NULL;
1680       }
1681     }
1682
1683   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1684     return 1;                   /* not defined nothing more to check  */
1685
1686   /* check if body already present */
1687   if (csym && IFFUNC_HASBODY(csym->type))
1688     {
1689       werror (E_FUNC_BODY, sym->name);
1690       return 0;
1691     }
1692
1693   /* check the return value type   */
1694   if (compareType (csym->type, sym->type) <= 0)
1695     {
1696       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1697       printFromToType(csym->type, sym->type);
1698       return 0;
1699     }
1700
1701   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1702     {
1703       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1704     }
1705
1706   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1707     {
1708       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1709     }
1710
1711   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1712     {
1713       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1714     }
1715
1716   /* compare expected args with actual args */
1717   exargs = FUNC_ARGS(csym->type);
1718   acargs = FUNC_ARGS(sym->type);
1719
1720   /* for all the expected args do */
1721   for (argCnt = 1;
1722        exargs && acargs;
1723        exargs = exargs->next, acargs = acargs->next, argCnt++)
1724     {
1725       if (getenv("DEBUG_SANITY")) {
1726         fprintf (stderr, "checkFunction: %s ", exargs->name);
1727       }
1728       /* make sure the type is complete and sane */
1729       checkTypeSanity(exargs->etype, exargs->name);
1730
1731       /* If the actual argument is an array, any prototype
1732        * will have modified it to a pointer. Duplicate that
1733        * change here.
1734        */
1735       if (IS_AGGREGATE (acargs->type))
1736         {
1737           checkValue = copyValue (acargs);
1738           aggregateToPointer (checkValue);
1739         }
1740       else
1741         {
1742           checkValue = acargs;
1743         }
1744
1745       if (compareType (exargs->type, checkValue->type) <= 0)
1746         {
1747           werror (E_ARG_TYPE, argCnt);
1748           printFromToType(exargs->type, checkValue->type);
1749           return 0;
1750         }
1751     }
1752
1753   /* if one them ended we have a problem */
1754   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1755       (!exargs && acargs && !IS_VOID (acargs->type)))
1756     werror (E_ARG_COUNT);
1757
1758   /* replace with this defition */
1759   sym->cdef = csym->cdef;
1760   deleteSym (SymbolTab, csym, csym->name);
1761   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1762   if (IS_EXTERN (csym->etype) && !
1763       IS_EXTERN (sym->etype))
1764     {
1765       addSet (&publics, sym);
1766     }
1767   return 1;
1768 }
1769
1770 /*-----------------------------------------------------------------*/
1771 /* processFuncArgs - does some processing with function args       */
1772 /*-----------------------------------------------------------------*/
1773 void 
1774 processFuncArgs (symbol * func)
1775 {
1776   value *val;
1777   int pNum = 1;
1778   sym_link *funcType=func->type;
1779
1780   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1781     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1782
1783   // if this is a pointer to a function
1784   if (IS_PTR(funcType)) {
1785     funcType=funcType->next;
1786   }
1787
1788   /* if this function has variable argument list */
1789   /* then make the function a reentrant one    */
1790   if (IFFUNC_HASVARARGS(funcType))
1791     FUNC_ISREENT(funcType)=1;
1792
1793   /* check if this function is defined as calleeSaves
1794      then mark it as such */
1795   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1796
1797   /* loop thru all the arguments   */
1798   val = FUNC_ARGS(funcType);
1799
1800   /* if it is void then remove parameters */
1801   if (val && IS_VOID (val->type))
1802     {
1803       FUNC_ARGS(funcType) = NULL;
1804       return;
1805     }
1806
1807   /* reset regparm for the port */
1808   (*port->reset_regparms) ();
1809   /* if any of the arguments is an aggregate */
1810   /* change it to pointer to the same type */
1811   while (val)
1812     {
1813       /* mark it as a register parameter if
1814          the function does not have VA_ARG
1815          and as port dictates */
1816       if (!IFFUNC_HASVARARGS(funcType) &&
1817           (*port->reg_parm) (val->type))
1818         {
1819           SPEC_REGPARM (val->etype) = 1;
1820         }
1821
1822       if (IS_AGGREGATE (val->type))
1823         {
1824           aggregateToPointer (val);
1825         }
1826
1827       val = val->next;
1828       pNum++;
1829     }
1830
1831   /* if this is an internal generated function call */
1832   if (func->cdef) {
1833     /* ignore --stack-auto for this one, we don't know how it is compiled */
1834     /* simply trust on --int-long-reent or --float-reent */
1835     if (IFFUNC_ISREENT(funcType)) {
1836       return;
1837     }
1838   } else {
1839     /* if this function is reentrant or */
1840     /* automatics r 2b stacked then nothing */
1841     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1842       return;
1843   }
1844
1845   val = FUNC_ARGS(funcType);
1846   pNum = 1;
1847   while (val)
1848     {
1849
1850       /* if a symbolname is not given  */
1851       /* synthesize a variable name */
1852       if (!val->sym)
1853         {
1854
1855           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1856           val->sym = newSymbol (val->name, 1);
1857           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1858           val->sym->type = copyLinkChain (val->type);
1859           val->sym->etype = getSpec (val->sym->type);
1860           val->sym->_isparm = 1;
1861           strcpy (val->sym->rname, val->name);
1862           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1863             SPEC_STAT (func->etype);
1864           addSymChain (val->sym);
1865
1866         }
1867       else                      /* symbol name given create synth name */
1868         {
1869
1870           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1871           strcpy (val->sym->rname, val->name);
1872           val->sym->_isparm = 1;
1873           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1874             (options.model != MODEL_SMALL ? xdata : data);
1875           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1876             SPEC_STAT (func->etype);
1877         }
1878       val = val->next;
1879     }
1880 }
1881
1882 /*-----------------------------------------------------------------*/
1883 /* isSymbolEqual - compares two symbols return 1 if they match     */
1884 /*-----------------------------------------------------------------*/
1885 int 
1886 isSymbolEqual (symbol * dest, symbol * src)
1887 {
1888   /* if pointers match then equal */
1889   if (dest == src)
1890     return 1;
1891
1892   /* if one of them is null then don't match */
1893   if (!dest || !src)
1894     return 0;
1895
1896   /* if both of them have rname match on rname */
1897   if (dest->rname[0] && src->rname[0])
1898     return (!strcmp (dest->rname, src->rname));
1899
1900   /* otherwise match on name */
1901   return (!strcmp (dest->name, src->name));
1902 }
1903
1904 void PT(sym_link *type)
1905 {
1906         printTypeChain(type,0);
1907 }
1908 /*-----------------------------------------------------------------*/
1909 /* printTypeChain - prints the type chain in human readable form   */
1910 /*-----------------------------------------------------------------*/
1911 void
1912 printTypeChain (sym_link * start, FILE * of)
1913 {
1914   int nlr = 0;
1915   sym_link * type, * search;
1916
1917   if (!of)
1918     {
1919       of = stdout;
1920       nlr = 1;
1921     }
1922
1923   if (start==NULL) {
1924     fprintf (of, "void");
1925     return;
1926   }
1927
1928   /* print the chain as it is written in the source: */
1929   /* start with the last entry                       */
1930   for (type = start; type && type->next; type = type->next)
1931     ;
1932   while (type)
1933     {
1934       if (IS_DECL (type))
1935         {
1936           if (DCL_PTR_VOLATILE (type)) {
1937             fprintf (of, "volatile ");
1938           }
1939           switch (DCL_TYPE (type))
1940             {
1941             case FUNCTION:
1942               fprintf (of, "function ");
1943               break;
1944             case GPOINTER:
1945               if (DCL_PTR_CONST (type))
1946                 fprintf (of, "const ");
1947               fprintf (of, "generic * ");
1948               break;
1949             case CPOINTER:
1950               if (DCL_PTR_CONST (type))
1951                 fprintf (of, "const ");
1952               fprintf (of, "code * ");
1953               break;
1954             case FPOINTER:
1955               if (DCL_PTR_CONST (type))
1956                 fprintf (of, "const ");
1957               fprintf (of, "xdata * ");
1958               break;
1959             case EEPPOINTER:
1960               if (DCL_PTR_CONST (type))
1961                 fprintf (of, "const ");
1962               fprintf (of, "eeprom * ");
1963               break;
1964
1965             case POINTER:
1966               if (DCL_PTR_CONST (type))
1967                 fprintf (of, "const ");
1968               fprintf (of, "near *");
1969               break;
1970             case IPOINTER:
1971               if (DCL_PTR_CONST (type))
1972                 fprintf (of, "const ");
1973               fprintf (of, "idata * ");
1974               break;
1975             case PPOINTER:
1976               if (DCL_PTR_CONST (type))
1977                 fprintf (of, "const ");
1978               fprintf (of, "pdata * ");
1979               break;
1980             case UPOINTER:
1981               if (DCL_PTR_CONST (type))
1982                 fprintf (of, "const ");
1983               fprintf (of, "unkown * ");
1984               break;
1985             case ARRAY:
1986               fprintf (of, "[] ");
1987               break;
1988             }
1989         }
1990       else
1991         {
1992           switch (SPEC_SCLS(type)) 
1993             {
1994             case S_DATA: fprintf (of, "data "); break;
1995             case S_XDATA: fprintf (of, "xdata "); break;
1996             case S_SFR: fprintf (of, "sfr "); break;
1997             case S_SBIT: fprintf (of, "sbit "); break;
1998             case S_CODE: fprintf (of, "code "); break;
1999             case S_IDATA: fprintf (of, "idata "); break;
2000             case S_PDATA: fprintf (of, "pdata "); break;
2001             case S_LITERAL: fprintf (of, "literal "); break;
2002             case S_STACK: fprintf (of, "stack "); break;
2003             case S_XSTACK: fprintf (of, "xstack "); break;
2004             case S_BIT: fprintf (of, "bit "); break;
2005             case S_EEPROM: fprintf (of, "eeprom "); break;
2006             default: break;
2007             }
2008
2009           if (SPEC_VOLATILE (type))
2010             fprintf (of, "volatile ");
2011           if (SPEC_USIGN (type))
2012             fprintf (of, "unsigned ");
2013           if (SPEC_CONST (type))
2014             fprintf (of, "const ");
2015
2016           switch (SPEC_NOUN (type))
2017             {
2018             case V_INT:
2019               if (IS_LONG (type))
2020                 fprintf (of, "long ");
2021               fprintf (of, "int");
2022               break;
2023
2024             case V_CHAR:
2025               fprintf (of, "char");
2026               break;
2027
2028             case V_VOID:
2029               fprintf (of, "void");
2030               break;
2031
2032             case V_FLOAT:
2033               fprintf (of, "float");
2034               break;
2035
2036             case V_STRUCT:
2037               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2038               break;
2039
2040             case V_SBIT:
2041               fprintf (of, "sbit");
2042               break;
2043
2044             case V_BIT:
2045               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2046               break;
2047
2048             case V_DOUBLE:
2049               fprintf (of, "double");
2050               break;
2051
2052             default:
2053               fprintf (of, "unknown type");
2054               break;
2055             }
2056         }
2057         /* search entry in list before "type" */
2058     for (search = start; search && search->next != type;)
2059        search = search->next;
2060     type = search;
2061     if (type)
2062       fputc (' ', of);
2063     }
2064   if (nlr)
2065     fprintf (of, "\n");
2066 }
2067
2068 /*-----------------------------------------------------------------*/
2069 /* cdbTypeInfo - print the type information for debugger           */
2070 /*-----------------------------------------------------------------*/
2071 void
2072 cdbTypeInfo (sym_link * type, FILE * of)
2073 {
2074   fprintf (of, "{%d}", getSize (type));
2075   while (type)
2076     {
2077       if (IS_DECL (type))
2078         {
2079           switch (DCL_TYPE (type))
2080             {
2081             case FUNCTION:
2082               fprintf (of, "DF,");
2083               break;
2084             case GPOINTER:
2085               fprintf (of, "DG,");
2086               break;
2087             case CPOINTER:
2088               fprintf (of, "DC,");
2089               break;
2090             case FPOINTER:
2091               fprintf (of, "DX,");
2092               break;
2093             case POINTER:
2094               fprintf (of, "DD,");
2095               break;
2096             case IPOINTER:
2097               fprintf (of, "DI,");
2098               break;
2099             case PPOINTER:
2100               fprintf (of, "DP,");
2101               break;
2102             case EEPPOINTER:
2103               fprintf (of, "DA,");
2104               break;
2105             case ARRAY:
2106               fprintf (of, "DA%d,", DCL_ELEM (type));
2107               break;
2108             default:
2109               break;
2110             }
2111         }
2112       else
2113         {
2114           switch (SPEC_NOUN (type))
2115             {
2116             case V_INT:
2117               if (IS_LONG (type))
2118                 fprintf (of, "SL");
2119               else
2120                 fprintf (of, "SI");
2121               break;
2122
2123             case V_CHAR:
2124               fprintf (of, "SC");
2125               break;
2126
2127             case V_VOID:
2128               fprintf (of, "SV");
2129               break;
2130
2131             case V_FLOAT:
2132               fprintf (of, "SF");
2133               break;
2134
2135             case V_STRUCT:
2136               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2137               break;
2138
2139             case V_SBIT:
2140               fprintf (of, "SX");
2141               break;
2142
2143             case V_BIT:
2144               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2145               break;
2146
2147             default:
2148               break;
2149             }
2150           fputs (":", of);
2151           if (SPEC_USIGN (type))
2152             fputs ("U", of);
2153           else
2154             fputs ("S", of);
2155         }
2156       type = type->next;
2157     }
2158 }
2159 /*-----------------------------------------------------------------*/
2160 /* cdbSymbol - prints a symbol & its type information for debugger */
2161 /*-----------------------------------------------------------------*/
2162 void 
2163 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2164 {
2165   memmap *map;
2166
2167   if (!sym)
2168     return;
2169   if (!of)
2170     of = stdout;
2171
2172   if (isFunc)
2173     fprintf (of, "F:");
2174   else
2175     fprintf (of, "S:");         /* symbol record */
2176   /* if this is not a structure symbol then
2177      we need to figure out the scope information */
2178   if (!isStructSym)
2179     {
2180       if (!sym->level)
2181         {
2182           /* global */
2183           if (IS_STATIC (sym->etype))
2184             fprintf (of, "F%s$", moduleName);   /* scope is file */
2185           else
2186             fprintf (of, "G$"); /* scope is global */
2187         }
2188       else
2189         /* symbol is local */
2190         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2191     }
2192   else
2193     fprintf (of, "S$");         /* scope is structure */
2194
2195   /* print the name, & mangled name */
2196   fprintf (of, "%s$%d$%d(", sym->name,
2197            sym->level, sym->block);
2198
2199   cdbTypeInfo (sym->type, of);
2200   fprintf (of, "),");
2201
2202   /* print the address space */
2203   map = SPEC_OCLS (sym->etype);
2204   fprintf (of, "%c,%d,%d",
2205            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2206
2207   /* if assigned to registers then output register names */
2208   /* if this is a function then print
2209      if is it an interrupt routine & interrupt number
2210      and the register bank it is using */
2211   if (isFunc)
2212     fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
2213              FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
2214   /* alternate location to find this symbol @ : eg registers
2215      or spillication */
2216
2217   if (!isStructSym)
2218     fprintf (of, "\n");
2219 }
2220
2221 /*-----------------------------------------------------------------*/
2222 /* cdbStruct - print a structure for debugger                      */
2223 /*-----------------------------------------------------------------*/
2224 void 
2225 cdbStruct (structdef * sdef, int block, FILE * of,
2226            int inStruct, char *tag)
2227 {
2228   symbol *sym;
2229
2230   fprintf (of, "T:");
2231   /* if block # then must have function scope */
2232   fprintf (of, "F%s$", moduleName);
2233   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2234   for (sym = sdef->fields; sym; sym = sym->next)
2235     {
2236       fprintf (of, "({%d}", sym->offset);
2237       cdbSymbol (sym, of, TRUE, FALSE);
2238       fprintf (of, ")");
2239     }
2240   fprintf (of, "]");
2241   if (!inStruct)
2242     fprintf (of, "\n");
2243 }
2244
2245 /*------------------------------------------------------------------*/
2246 /* cdbStructBlock - calls struct printing for a blcks               */
2247 /*------------------------------------------------------------------*/
2248 void 
2249 cdbStructBlock (int block, FILE * of)
2250 {
2251   int i;
2252   bucket **table = StructTab;
2253   bucket *chain;
2254   wassert (of);
2255
2256   /* go thru the entire  table  */
2257   for (i = 0; i < 256; i++)
2258     {
2259       for (chain = table[i]; chain; chain = chain->next)
2260         {
2261           if (chain->block >= block)
2262             {
2263               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2264             }
2265         }
2266     }
2267 }
2268
2269 /*-----------------------------------------------------------------*/
2270 /* powof2 - returns power of two for the number if number is pow 2 */
2271 /*-----------------------------------------------------------------*/
2272 int 
2273 powof2 (unsigned long num)
2274 {
2275   int nshifts = 0;
2276   int n1s = 0;
2277
2278   while (num)
2279     {
2280       if (num & 1)
2281         n1s++;
2282       num >>= 1;
2283       nshifts++;
2284     }
2285
2286   if (n1s > 1 || nshifts == 0)
2287     return 0;
2288   return nshifts - 1;
2289 }
2290
2291 symbol *__fsadd;
2292 symbol *__fssub;
2293 symbol *__fsmul;
2294 symbol *__fsdiv;
2295 symbol *__fseq;
2296 symbol *__fsneq;
2297 symbol *__fslt;
2298 symbol *__fslteq;
2299 symbol *__fsgt;
2300 symbol *__fsgteq;
2301
2302 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2303 symbol *__muldiv[3][3][2];
2304 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2305 sym_link *__multypes[3][2];
2306 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2307 symbol *__conv[2][3][2];
2308 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2309 symbol *__rlrr[2][3][2];
2310
2311 sym_link *floatType;
2312
2313 static char *
2314 _mangleFunctionName(char *in)
2315 {
2316   if (port->getMangledFunctionName) 
2317     {
2318       return port->getMangledFunctionName(in);
2319     }
2320   else
2321     {
2322       return in;
2323     }
2324 }
2325
2326 /*-----------------------------------------------------------------*/
2327 /* initCSupport - create functions for C support routines          */
2328 /*-----------------------------------------------------------------*/
2329 void 
2330 initCSupport ()
2331 {
2332   const char *smuldivmod[] =
2333   {
2334     "mul", "div", "mod"
2335   };
2336   const char *sbwd[] =
2337   {
2338     "char", "int", "long"
2339   };
2340   const char *ssu[] =
2341   {
2342     "s", "u"
2343   };
2344   const char *srlrr[] =
2345   {
2346     "rl", "rr"
2347   };
2348
2349   int bwd, su, muldivmod, tofrom, rlrr;
2350
2351   if (getenv("SDCC_NO_C_SUPPORT")) {
2352     /* for debugging only */
2353     return;
2354   }
2355
2356   floatType = newFloatLink ();
2357
2358   for (bwd = 0; bwd < 3; bwd++)
2359     {
2360       sym_link *l;
2361       switch (bwd)
2362         {
2363         case 0:
2364           l = newCharLink ();
2365           break;
2366         case 1:
2367           l = newIntLink ();
2368           break;
2369         case 2:
2370           l = newLongLink ();
2371           break;
2372         default:
2373           assert (0);
2374         }
2375       __multypes[bwd][0] = l;
2376       __multypes[bwd][1] = copyLinkChain (l);
2377       SPEC_USIGN (__multypes[bwd][1]) = 1;
2378     }
2379
2380   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2381   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2382   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2383   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2384   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2385   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2386   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2387   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2388   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2389   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2390
2391   for (tofrom = 0; tofrom < 2; tofrom++)
2392     {
2393       for (bwd = 0; bwd < 3; bwd++)
2394         {
2395           for (su = 0; su < 2; su++)
2396             {
2397               if (tofrom)
2398                 {
2399                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2400                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
2401                 }
2402               else
2403                 {
2404                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2405                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
2406                 }
2407             }
2408         }
2409     }
2410
2411   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2412     {
2413       for (bwd = 0; bwd < 3; bwd++)
2414         {
2415           for (su = 0; su < 2; su++)
2416             {
2417               sprintf (buffer, "_%s%s%s",
2418                        smuldivmod[muldivmod],
2419                        ssu[su],
2420                        sbwd[bwd]);
2421               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2422               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2423             }
2424         }
2425     }
2426
2427   for (rlrr = 0; rlrr < 2; rlrr++)
2428     {
2429       for (bwd = 0; bwd < 3; bwd++)
2430         {
2431           for (su = 0; su < 2; su++)
2432             {
2433               sprintf (buffer, "_%s%s%s",
2434                        srlrr[rlrr],
2435                        ssu[su],
2436                        sbwd[bwd]);
2437               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2438               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2439             }
2440         }
2441     }
2442 }