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