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