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