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