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