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