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