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