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