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