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