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