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