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