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