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