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