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