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