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