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