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