afedc3e53ce77719f6e3e7e93bd23e0b8de3c4de
[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             DCL_TYPE(val->type)=PTR_TYPE(SPEC_OCLS(val->etype));
1586
1587           if (TARGET_IS_DS390)
1588             {
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           break;
1601         case S_AUTO:
1602         case S_DATA:
1603         case S_REGISTER:
1604           DCL_TYPE (val->type) = POINTER;
1605           break;
1606         case S_CODE:
1607           DCL_TYPE (val->type) = CPOINTER;
1608           break;
1609         case S_XDATA:
1610           DCL_TYPE (val->type) = FPOINTER;
1611           break;
1612         case S_EEPROM:
1613           DCL_TYPE (val->type) = EEPPOINTER;
1614           break;
1615         default:
1616           DCL_TYPE (val->type) = GPOINTER;
1617         }
1618       
1619       /* is there is a symbol associated then */
1620       /* change the type of the symbol as well */
1621       if (val->sym)
1622         {
1623           val->sym->type = copyLinkChain (val->type);
1624           val->sym->etype = getSpec (val->sym->type);
1625         }
1626     }
1627   return val;
1628 }
1629 /*------------------------------------------------------------------*/
1630 /* checkFunction - does all kinds of check on a function            */
1631 /*------------------------------------------------------------------*/
1632 int 
1633 checkFunction (symbol * sym, symbol *csym)
1634 {
1635   value *exargs, *acargs;
1636   value *checkValue;
1637   int argCnt = 0;
1638
1639   if (getenv("DEBUG_SANITY")) {
1640     fprintf (stderr, "checkFunction: %s ", sym->name);
1641   }
1642
1643   /* make sure the type is complete and sane */
1644   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1645
1646   /* if not type then some kind of error */
1647   if (!sym->type)
1648     return 0;
1649
1650   /* if the function has no type then make it return int */
1651   if (!sym->type->next)
1652     sym->type->next = sym->etype = newIntLink ();
1653
1654   /* function cannot return aggregate */
1655   if (IS_AGGREGATE (sym->type->next))
1656     {
1657       werror (E_FUNC_AGGR, sym->name);
1658       return 0;
1659     }
1660
1661   /* function cannot return bit */
1662   if (IS_BITVAR (sym->type->next))
1663     {
1664       werror (E_FUNC_BIT, sym->name);
1665       return 0;
1666     }
1667
1668   /* check if this function is defined as calleeSaves
1669      then mark it as such */
1670     FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1671
1672   /* if interrupt service routine  */
1673   /* then it cannot have arguments */
1674   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1675     {
1676       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1677         werror (E_INT_ARGS, sym->name);
1678         FUNC_ARGS(sym->type)=NULL;
1679       }
1680     }
1681
1682   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1683     return 1;                   /* not defined nothing more to check  */
1684
1685   /* check if body already present */
1686   if (csym && IFFUNC_HASBODY(csym->type))
1687     {
1688       werror (E_FUNC_BODY, sym->name);
1689       return 0;
1690     }
1691
1692   /* check the return value type   */
1693   if (compareType (csym->type, sym->type) <= 0)
1694     {
1695       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1696       printFromToType(csym->type, sym->type);
1697       return 0;
1698     }
1699
1700   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1701     {
1702       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1703     }
1704
1705   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1706     {
1707       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1708     }
1709
1710   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1711     {
1712       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1713     }
1714
1715   /* compare expected args with actual args */
1716   exargs = FUNC_ARGS(csym->type);
1717   acargs = FUNC_ARGS(sym->type);
1718
1719   /* for all the expected args do */
1720   for (argCnt = 1;
1721        exargs && acargs;
1722        exargs = exargs->next, acargs = acargs->next, argCnt++)
1723     {
1724       if (getenv("DEBUG_SANITY")) {
1725         fprintf (stderr, "checkFunction: %s ", exargs->name);
1726       }
1727       /* make sure the type is complete and sane */
1728       checkTypeSanity(exargs->etype, exargs->name);
1729
1730       /* If the actual argument is an array, any prototype
1731        * will have modified it to a pointer. Duplicate that
1732        * change here.
1733        */
1734       if (IS_AGGREGATE (acargs->type))
1735         {
1736           checkValue = copyValue (acargs);
1737           aggregateToPointer (checkValue);
1738         }
1739       else
1740         {
1741           checkValue = acargs;
1742         }
1743
1744       if (compareType (exargs->type, checkValue->type) <= 0)
1745         {
1746           werror (E_ARG_TYPE, argCnt);
1747           printFromToType(exargs->type, checkValue->type);
1748           return 0;
1749         }
1750     }
1751
1752   /* if one them ended we have a problem */
1753   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1754       (!exargs && acargs && !IS_VOID (acargs->type)))
1755     werror (E_ARG_COUNT);
1756
1757   /* replace with this defition */
1758   sym->cdef = csym->cdef;
1759   deleteSym (SymbolTab, csym, csym->name);
1760   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1761   if (IS_EXTERN (csym->etype) && !
1762       IS_EXTERN (sym->etype))
1763     {
1764       addSet (&publics, sym);
1765     }
1766   return 1;
1767 }
1768
1769 /*-----------------------------------------------------------------*/
1770 /* processFuncArgs - does some processing with function args       */
1771 /*-----------------------------------------------------------------*/
1772 void 
1773 processFuncArgs (symbol * func)
1774 {
1775   value *val;
1776   int pNum = 1;
1777   sym_link *funcType=func->type;
1778
1779   if (getenv("SDCC_DEBUG_FUNCTION_POINTERS"))
1780     fprintf (stderr, "SDCCsymt.c:processFuncArgs(%s)\n", func->name);
1781
1782   // if this is a pointer to a function
1783   if (IS_PTR(funcType)) {
1784     funcType=funcType->next;
1785   }
1786
1787   /* if this function has variable argument list */
1788   /* then make the function a reentrant one    */
1789   if (IFFUNC_HASVARARGS(funcType))
1790     FUNC_ISREENT(funcType)=1;
1791
1792   /* check if this function is defined as calleeSaves
1793      then mark it as such */
1794   FUNC_CALLEESAVES(funcType) = inCalleeSaveList (func->name);
1795
1796   /* loop thru all the arguments   */
1797   val = FUNC_ARGS(funcType);
1798
1799   /* if it is void then remove parameters */
1800   if (val && IS_VOID (val->type))
1801     {
1802       FUNC_ARGS(funcType) = NULL;
1803       return;
1804     }
1805
1806   /* reset regparm for the port */
1807   (*port->reset_regparms) ();
1808   /* if any of the arguments is an aggregate */
1809   /* change it to pointer to the same type */
1810   while (val)
1811     {
1812       /* mark it as a register parameter if
1813          the function does not have VA_ARG
1814          and as port dictates */
1815       if (!IFFUNC_HASVARARGS(funcType) &&
1816           (*port->reg_parm) (val->type))
1817         {
1818           SPEC_REGPARM (val->etype) = 1;
1819         }
1820
1821       if (IS_AGGREGATE (val->type))
1822         {
1823           aggregateToPointer (val);
1824         }
1825
1826       val = val->next;
1827       pNum++;
1828     }
1829
1830   /* if this is an internal generated function call */
1831   if (func->cdef) {
1832     /* ignore --stack-auto for this one, we don't know how it is compiled */
1833     /* simply trust on --int-long-reent or --float-reent */
1834     if (IFFUNC_ISREENT(funcType)) {
1835       return;
1836     }
1837   } else {
1838     /* if this function is reentrant or */
1839     /* automatics r 2b stacked then nothing */
1840     if (IFFUNC_ISREENT (funcType) || options.stackAuto)
1841       return;
1842   }
1843
1844   val = FUNC_ARGS(funcType);
1845   pNum = 1;
1846   while (val)
1847     {
1848
1849       /* if a symbolname is not given  */
1850       /* synthesize a variable name */
1851       if (!val->sym)
1852         {
1853
1854           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1855           val->sym = newSymbol (val->name, 1);
1856           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1857           val->sym->type = copyLinkChain (val->type);
1858           val->sym->etype = getSpec (val->sym->type);
1859           val->sym->_isparm = 1;
1860           strcpy (val->sym->rname, val->name);
1861           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1862             SPEC_STAT (func->etype);
1863           addSymChain (val->sym);
1864
1865         }
1866       else                      /* symbol name given create synth name */
1867         {
1868
1869           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1870           strcpy (val->sym->rname, val->name);
1871           val->sym->_isparm = 1;
1872           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1873             (options.model != MODEL_SMALL ? xdata : data);
1874           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1875             SPEC_STAT (func->etype);
1876         }
1877       val = val->next;
1878     }
1879 }
1880
1881 /*-----------------------------------------------------------------*/
1882 /* isSymbolEqual - compares two symbols return 1 if they match     */
1883 /*-----------------------------------------------------------------*/
1884 int 
1885 isSymbolEqual (symbol * dest, symbol * src)
1886 {
1887   /* if pointers match then equal */
1888   if (dest == src)
1889     return 1;
1890
1891   /* if one of them is null then don't match */
1892   if (!dest || !src)
1893     return 0;
1894
1895   /* if both of them have rname match on rname */
1896   if (dest->rname[0] && src->rname[0])
1897     return (!strcmp (dest->rname, src->rname));
1898
1899   /* otherwise match on name */
1900   return (!strcmp (dest->name, src->name));
1901 }
1902
1903 void PT(sym_link *type)
1904 {
1905         printTypeChain(type,0);
1906 }
1907 /*-----------------------------------------------------------------*/
1908 /* printTypeChain - prints the type chain in human readable form   */
1909 /*-----------------------------------------------------------------*/
1910 void
1911 printTypeChain (sym_link * start, FILE * of)
1912 {
1913   int nlr = 0;
1914   sym_link * type, * search;
1915
1916   if (!of)
1917     {
1918       of = stdout;
1919       nlr = 1;
1920     }
1921
1922   if (start==NULL) {
1923     fprintf (of, "void");
1924     return;
1925   }
1926
1927   /* print the chain as it is written in the source: */
1928   /* start with the last entry                       */
1929   for (type = start; type && type->next; type = type->next)
1930     ;
1931   while (type)
1932     {
1933       if (IS_DECL (type))
1934         {
1935           if (DCL_PTR_VOLATILE (type)) {
1936             fprintf (of, "volatile ");
1937           }
1938           switch (DCL_TYPE (type))
1939             {
1940             case FUNCTION:
1941               fprintf (of, "function ");
1942               break;
1943             case GPOINTER:
1944               if (DCL_PTR_CONST (type))
1945                 fprintf (of, "const ");
1946               fprintf (of, "generic * ");
1947               break;
1948             case CPOINTER:
1949               if (DCL_PTR_CONST (type))
1950                 fprintf (of, "const ");
1951               fprintf (of, "code * ");
1952               break;
1953             case FPOINTER:
1954               if (DCL_PTR_CONST (type))
1955                 fprintf (of, "const ");
1956               fprintf (of, "xdata * ");
1957               break;
1958             case EEPPOINTER:
1959               if (DCL_PTR_CONST (type))
1960                 fprintf (of, "const ");
1961               fprintf (of, "eeprom * ");
1962               break;
1963
1964             case POINTER:
1965               if (DCL_PTR_CONST (type))
1966                 fprintf (of, "const ");
1967               fprintf (of, "near *");
1968               break;
1969             case IPOINTER:
1970               if (DCL_PTR_CONST (type))
1971                 fprintf (of, "const ");
1972               fprintf (of, "idata * ");
1973               break;
1974             case PPOINTER:
1975               if (DCL_PTR_CONST (type))
1976                 fprintf (of, "const ");
1977               fprintf (of, "pdata * ");
1978               break;
1979             case UPOINTER:
1980               if (DCL_PTR_CONST (type))
1981                 fprintf (of, "const ");
1982               fprintf (of, "unkown * ");
1983               break;
1984             case ARRAY:
1985               fprintf (of, "[] ");
1986               break;
1987             }
1988         }
1989       else
1990         {
1991           switch (SPEC_SCLS(type)) 
1992             {
1993             case S_DATA: fprintf (of, "data "); break;
1994             case S_XDATA: fprintf (of, "xdata "); break;
1995             case S_SFR: fprintf (of, "sfr "); break;
1996             case S_SBIT: fprintf (of, "sbit "); break;
1997             case S_CODE: fprintf (of, "code "); break;
1998             case S_IDATA: fprintf (of, "idata "); break;
1999             case S_PDATA: fprintf (of, "pdata "); break;
2000             case S_LITERAL: fprintf (of, "literal "); break;
2001             case S_STACK: fprintf (of, "stack "); break;
2002             case S_XSTACK: fprintf (of, "xstack "); break;
2003             case S_BIT: fprintf (of, "bit "); break;
2004             case S_EEPROM: fprintf (of, "eeprom "); break;
2005             default: break;
2006             }
2007
2008           if (SPEC_VOLATILE (type))
2009             fprintf (of, "volatile ");
2010           if (SPEC_USIGN (type))
2011             fprintf (of, "unsigned ");
2012           if (SPEC_CONST (type))
2013             fprintf (of, "const ");
2014
2015           switch (SPEC_NOUN (type))
2016             {
2017             case V_INT:
2018               if (IS_LONG (type))
2019                 fprintf (of, "long ");
2020               fprintf (of, "int");
2021               break;
2022
2023             case V_CHAR:
2024               fprintf (of, "char");
2025               break;
2026
2027             case V_VOID:
2028               fprintf (of, "void");
2029               break;
2030
2031             case V_FLOAT:
2032               fprintf (of, "float");
2033               break;
2034
2035             case V_STRUCT:
2036               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2037               break;
2038
2039             case V_SBIT:
2040               fprintf (of, "sbit");
2041               break;
2042
2043             case V_BIT:
2044               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2045               break;
2046
2047             case V_DOUBLE:
2048               fprintf (of, "double");
2049               break;
2050
2051             default:
2052               fprintf (of, "unknown type");
2053               break;
2054             }
2055         }
2056         /* search entry in list before "type" */
2057     for (search = start; search && search->next != type;)
2058        search = search->next;
2059     type = search;
2060     if (type)
2061       fputc (' ', of);
2062     }
2063   if (nlr)
2064     fprintf (of, "\n");
2065 }
2066
2067 /*-----------------------------------------------------------------*/
2068 /* cdbTypeInfo - print the type information for debugger           */
2069 /*-----------------------------------------------------------------*/
2070 void
2071 cdbTypeInfo (sym_link * type, FILE * of)
2072 {
2073   fprintf (of, "{%d}", getSize (type));
2074   while (type)
2075     {
2076       if (IS_DECL (type))
2077         {
2078           switch (DCL_TYPE (type))
2079             {
2080             case FUNCTION:
2081               fprintf (of, "DF,");
2082               break;
2083             case GPOINTER:
2084               fprintf (of, "DG,");
2085               break;
2086             case CPOINTER:
2087               fprintf (of, "DC,");
2088               break;
2089             case FPOINTER:
2090               fprintf (of, "DX,");
2091               break;
2092             case POINTER:
2093               fprintf (of, "DD,");
2094               break;
2095             case IPOINTER:
2096               fprintf (of, "DI,");
2097               break;
2098             case PPOINTER:
2099               fprintf (of, "DP,");
2100               break;
2101             case EEPPOINTER:
2102               fprintf (of, "DA,");
2103               break;
2104             case ARRAY:
2105               fprintf (of, "DA%d,", DCL_ELEM (type));
2106               break;
2107             default:
2108               break;
2109             }
2110         }
2111       else
2112         {
2113           switch (SPEC_NOUN (type))
2114             {
2115             case V_INT:
2116               if (IS_LONG (type))
2117                 fprintf (of, "SL");
2118               else
2119                 fprintf (of, "SI");
2120               break;
2121
2122             case V_CHAR:
2123               fprintf (of, "SC");
2124               break;
2125
2126             case V_VOID:
2127               fprintf (of, "SV");
2128               break;
2129
2130             case V_FLOAT:
2131               fprintf (of, "SF");
2132               break;
2133
2134             case V_STRUCT:
2135               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2136               break;
2137
2138             case V_SBIT:
2139               fprintf (of, "SX");
2140               break;
2141
2142             case V_BIT:
2143               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2144               break;
2145
2146             default:
2147               break;
2148             }
2149           fputs (":", of);
2150           if (SPEC_USIGN (type))
2151             fputs ("U", of);
2152           else
2153             fputs ("S", of);
2154         }
2155       type = type->next;
2156     }
2157 }
2158 /*-----------------------------------------------------------------*/
2159 /* cdbSymbol - prints a symbol & its type information for debugger */
2160 /*-----------------------------------------------------------------*/
2161 void 
2162 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2163 {
2164   memmap *map;
2165
2166   if (!sym)
2167     return;
2168   if (!of)
2169     of = stdout;
2170
2171   if (isFunc)
2172     fprintf (of, "F:");
2173   else
2174     fprintf (of, "S:");         /* symbol record */
2175   /* if this is not a structure symbol then
2176      we need to figure out the scope information */
2177   if (!isStructSym)
2178     {
2179       if (!sym->level)
2180         {
2181           /* global */
2182           if (IS_STATIC (sym->etype))
2183             fprintf (of, "F%s$", moduleName);   /* scope is file */
2184           else
2185             fprintf (of, "G$"); /* scope is global */
2186         }
2187       else
2188         /* symbol is local */
2189         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2190     }
2191   else
2192     fprintf (of, "S$");         /* scope is structure */
2193
2194   /* print the name, & mangled name */
2195   fprintf (of, "%s$%d$%d(", sym->name,
2196            sym->level, sym->block);
2197
2198   cdbTypeInfo (sym->type, of);
2199   fprintf (of, "),");
2200
2201   /* print the address space */
2202   map = SPEC_OCLS (sym->etype);
2203   fprintf (of, "%c,%d,%d",
2204            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2205
2206   /* if assigned to registers then output register names */
2207   /* if this is a function then print
2208      if is it an interrupt routine & interrupt number
2209      and the register bank it is using */
2210   if (isFunc)
2211     fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
2212              FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
2213   /* alternate location to find this symbol @ : eg registers
2214      or spillication */
2215
2216   if (!isStructSym)
2217     fprintf (of, "\n");
2218 }
2219
2220 /*-----------------------------------------------------------------*/
2221 /* cdbStruct - print a structure for debugger                      */
2222 /*-----------------------------------------------------------------*/
2223 void 
2224 cdbStruct (structdef * sdef, int block, FILE * of,
2225            int inStruct, char *tag)
2226 {
2227   symbol *sym;
2228
2229   fprintf (of, "T:");
2230   /* if block # then must have function scope */
2231   fprintf (of, "F%s$", moduleName);
2232   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2233   for (sym = sdef->fields; sym; sym = sym->next)
2234     {
2235       fprintf (of, "({%d}", sym->offset);
2236       cdbSymbol (sym, of, TRUE, FALSE);
2237       fprintf (of, ")");
2238     }
2239   fprintf (of, "]");
2240   if (!inStruct)
2241     fprintf (of, "\n");
2242 }
2243
2244 /*------------------------------------------------------------------*/
2245 /* cdbStructBlock - calls struct printing for a blcks               */
2246 /*------------------------------------------------------------------*/
2247 void 
2248 cdbStructBlock (int block, FILE * of)
2249 {
2250   int i;
2251   bucket **table = StructTab;
2252   bucket *chain;
2253   wassert (of);
2254
2255   /* go thru the entire  table  */
2256   for (i = 0; i < 256; i++)
2257     {
2258       for (chain = table[i]; chain; chain = chain->next)
2259         {
2260           if (chain->block >= block)
2261             {
2262               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2263             }
2264         }
2265     }
2266 }
2267
2268 /*-----------------------------------------------------------------*/
2269 /* powof2 - returns power of two for the number if number is pow 2 */
2270 /*-----------------------------------------------------------------*/
2271 int 
2272 powof2 (unsigned long num)
2273 {
2274   int nshifts = 0;
2275   int n1s = 0;
2276
2277   while (num)
2278     {
2279       if (num & 1)
2280         n1s++;
2281       num >>= 1;
2282       nshifts++;
2283     }
2284
2285   if (n1s > 1 || nshifts == 0)
2286     return 0;
2287   return nshifts - 1;
2288 }
2289
2290 symbol *__fsadd;
2291 symbol *__fssub;
2292 symbol *__fsmul;
2293 symbol *__fsdiv;
2294 symbol *__fseq;
2295 symbol *__fsneq;
2296 symbol *__fslt;
2297 symbol *__fslteq;
2298 symbol *__fsgt;
2299 symbol *__fsgteq;
2300
2301 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2302 symbol *__muldiv[3][3][2];
2303 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2304 sym_link *__multypes[3][2];
2305 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2306 symbol *__conv[2][3][2];
2307 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2308 symbol *__rlrr[2][3][2];
2309
2310 sym_link *floatType;
2311
2312 static char *
2313 _mangleFunctionName(char *in)
2314 {
2315   if (port->getMangledFunctionName) 
2316     {
2317       return port->getMangledFunctionName(in);
2318     }
2319   else
2320     {
2321       return in;
2322     }
2323 }
2324
2325 /*-----------------------------------------------------------------*/
2326 /* initCSupport - create functions for C support routines          */
2327 /*-----------------------------------------------------------------*/
2328 void 
2329 initCSupport ()
2330 {
2331   const char *smuldivmod[] =
2332   {
2333     "mul", "div", "mod"
2334   };
2335   const char *sbwd[] =
2336   {
2337     "char", "int", "long"
2338   };
2339   const char *ssu[] =
2340   {
2341     "s", "u"
2342   };
2343   const char *srlrr[] =
2344   {
2345     "rl", "rr"
2346   };
2347
2348   int bwd, su, muldivmod, tofrom, rlrr;
2349
2350   if (getenv("SDCC_NO_C_SUPPORT")) {
2351     /* for debugging only */
2352     return;
2353   }
2354
2355   floatType = newFloatLink ();
2356
2357   for (bwd = 0; bwd < 3; bwd++)
2358     {
2359       sym_link *l;
2360       switch (bwd)
2361         {
2362         case 0:
2363           l = newCharLink ();
2364           break;
2365         case 1:
2366           l = newIntLink ();
2367           break;
2368         case 2:
2369           l = newLongLink ();
2370           break;
2371         default:
2372           assert (0);
2373         }
2374       __multypes[bwd][0] = l;
2375       __multypes[bwd][1] = copyLinkChain (l);
2376       SPEC_USIGN (__multypes[bwd][1]) = 1;
2377     }
2378
2379   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2380   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2381   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2382   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2383   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2384   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2385   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2386   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2387   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2388   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2389
2390   for (tofrom = 0; tofrom < 2; tofrom++)
2391     {
2392       for (bwd = 0; bwd < 3; bwd++)
2393         {
2394           for (su = 0; su < 2; su++)
2395             {
2396               if (tofrom)
2397                 {
2398                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2399                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
2400                 }
2401               else
2402                 {
2403                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2404                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
2405                 }
2406             }
2407         }
2408     }
2409
2410   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2411     {
2412       for (bwd = 0; bwd < 3; bwd++)
2413         {
2414           for (su = 0; su < 2; su++)
2415             {
2416               sprintf (buffer, "_%s%s%s",
2417                        smuldivmod[muldivmod],
2418                        ssu[su],
2419                        sbwd[bwd]);
2420               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2421               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2422             }
2423         }
2424     }
2425
2426   for (rlrr = 0; rlrr < 2; rlrr++)
2427     {
2428       for (bwd = 0; bwd < 3; bwd++)
2429         {
2430           for (su = 0; su < 2; su++)
2431             {
2432               sprintf (buffer, "_%s%s%s",
2433                        srlrr[rlrr],
2434                        ssu[su],
2435                        sbwd[bwd]);
2436               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2437               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2438             }
2439         }
2440     }
2441 }