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