Now global consts are in CSEG again with the proper cast
[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   if (getenv("DEBUG_SANITY")) {
1112     fprintf (stderr, "checkSClass: %s \n", sym->name);
1113   }
1114   if (strcmp(sym->name, "_testsGlobal")==0) {
1115     printf ("oach\n");
1116   }
1117   
1118   /* type is literal can happen foe enums change
1119      to auto */
1120   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1121     SPEC_SCLS (sym->etype) = S_AUTO;
1122   
1123   /* if sfr or sbit then must also be */
1124   /* volatile the initial value will be xlated */
1125   /* to an absolute address */
1126   if (SPEC_SCLS (sym->etype) == S_SBIT ||
1127       SPEC_SCLS (sym->etype) == S_SFR)
1128     {
1129       SPEC_VOLATILE (sym->etype) = 1;
1130       /* if initial value given */
1131       if (sym->ival)
1132         {
1133           SPEC_ABSA (sym->etype) = 1;
1134           SPEC_ADDR (sym->etype) =
1135             (int) list2int (sym->ival);
1136           sym->ival = NULL;
1137         }
1138     }
1139   
1140   /* if absolute address given then it mark it as
1141      volatile */
1142   if (IS_ABSOLUTE (sym->etype))
1143     SPEC_VOLATILE (sym->etype) = 1;
1144   
1145   /* global variables declared const put into code */
1146   if (sym->level == 0 &&
1147       SPEC_CONST (sym->etype)) {
1148     SPEC_SCLS (sym->etype) = S_CODE;
1149   }
1150   
1151   /* global variable in code space is a constant */
1152   if (sym->level == 0 &&
1153       SPEC_SCLS (sym->etype) == S_CODE &&
1154       port->mem.code_ro)
1155     SPEC_CONST (sym->etype) = 1;
1156   
1157
1158   /* if bit variable then no storage class can be */
1159   /* specified since bit is already a storage */
1160   if (IS_BITVAR (sym->etype) &&
1161       (SPEC_SCLS (sym->etype) != S_FIXED &&
1162        SPEC_SCLS (sym->etype) != S_SBIT &&
1163        SPEC_SCLS (sym->etype) != S_BIT)
1164     )
1165     {
1166       werror (E_BITVAR_STORAGE, sym->name);
1167       SPEC_SCLS (sym->etype) = S_FIXED;
1168     }
1169
1170   /* extern variables cannot be initialized */
1171   if (IS_EXTERN (sym->etype) && sym->ival)
1172     {
1173       werror (E_EXTERN_INIT, sym->name);
1174       sym->ival = NULL;
1175     }
1176
1177   /* if this is an automatic symbol then */
1178   /* storage class will be ignored and   */
1179   /* symbol will be allocated on stack/  */
1180   /* data depending on flag             */
1181   if (sym->level &&
1182       (options.stackAuto || reentrant) &&
1183       (SPEC_SCLS (sym->etype) != S_AUTO &&
1184        SPEC_SCLS (sym->etype) != S_FIXED &&
1185        SPEC_SCLS (sym->etype) != S_REGISTER &&
1186        SPEC_SCLS (sym->etype) != S_STACK &&
1187        SPEC_SCLS (sym->etype) != S_XSTACK))
1188     {
1189       werror (E_AUTO_ASSUMED, sym->name);
1190       SPEC_SCLS (sym->etype) = S_AUTO;
1191     }
1192   
1193   /* automatic symbols cannot be given   */
1194   /* an absolute address ignore it      */
1195   if (sym->level &&
1196       SPEC_ABSA (sym->etype) &&
1197       (options.stackAuto || reentrant))
1198     {
1199       werror (E_AUTO_ABSA, sym->name);
1200       SPEC_ABSA (sym->etype) = 0;
1201     }
1202
1203   /* arrays & pointers cannot be defined for bits   */
1204   /* SBITS or SFRs or BIT                           */
1205   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1206       (SPEC_NOUN (sym->etype) == V_BIT ||
1207        SPEC_NOUN (sym->etype) == V_SBIT ||
1208        SPEC_SCLS (sym->etype) == S_SFR))
1209     werror (E_BIT_ARRAY, sym->name);
1210
1211   /* if this is a bit|sbit then set length & start  */
1212   if (SPEC_NOUN (sym->etype) == V_BIT ||
1213       SPEC_NOUN (sym->etype) == V_SBIT)
1214     {
1215       SPEC_BLEN (sym->etype) = 1;
1216       SPEC_BSTR (sym->etype) = 0;
1217     }
1218
1219   /* variables declared in CODE space must have */
1220   /* initializers if not an extern */
1221   if (SPEC_SCLS (sym->etype) == S_CODE &&
1222       sym->ival == NULL &&
1223       !sym->level &&
1224       port->mem.code_ro &&
1225       !IS_EXTERN (sym->etype) &&
1226       !funcInChain (sym->type))
1227     werror (E_CODE_NO_INIT, sym->name);
1228
1229   /* if parameter or local variable then change */
1230   /* the storage class to reflect where the var will go */
1231   if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1232       !IS_STATIC(sym->etype))
1233     {
1234       if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
1235         {
1236           SPEC_SCLS (sym->etype) = (options.useXstack ?
1237                                     S_XSTACK : S_STACK);
1238         }
1239       else
1240         {
1241           /* hack-o-matic! I see no reason why the useXstack option should ever
1242            * control this allcoation, but the code was originally that way, and
1243            * changing it for non-390 ports breaks the compiler badly.
1244            */
1245           bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1246           SPEC_SCLS (sym->etype) = (useXdata ?
1247                                     S_XDATA : S_FIXED);
1248         }
1249     }
1250 }
1251
1252 /*------------------------------------------------------------------*/
1253 /* changePointer - change pointer to functions                      */
1254 /*------------------------------------------------------------------*/
1255 void 
1256 changePointer (symbol * sym)
1257 {
1258   sym_link *p;
1259
1260   /* go thru the chain of declarations   */
1261   /* if we find a pointer to a function  */
1262   /* unconditionally change it to a ptr  */
1263   /* to code area                        */
1264   for (p = sym->type; p; p = p->next)
1265     {
1266       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1267         DCL_TYPE (p) = GPOINTER;
1268       if (IS_PTR (p) && IS_FUNC (p->next))
1269         DCL_TYPE (p) = CPOINTER;
1270     }
1271 }
1272
1273 /*------------------------------------------------------------------*/
1274 /* checkDecl - does semantic validation of a declaration                   */
1275 /*------------------------------------------------------------------*/
1276 int 
1277 checkDecl (symbol * sym)
1278 {
1279
1280   checkSClass (sym);            /* check the storage class      */
1281   changePointer (sym);          /* change pointers if required */
1282
1283   /* if this is an array without any dimension
1284      then update the dimension from the initial value */
1285   if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1286     DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1287
1288   return 0;
1289 }
1290
1291 /*------------------------------------------------------------------*/
1292 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1293 /*------------------------------------------------------------------*/
1294 sym_link *
1295 copyLinkChain (sym_link * p)
1296 {
1297   sym_link *head, *curr, *loop;
1298
1299   curr = p;
1300   head = loop = (curr ? newLink () : (void *) NULL);
1301   while (curr)
1302     {
1303       memcpy (loop, curr, sizeof (sym_link));   /* copy it */
1304       loop->next = (curr->next ? newLink () : (void *) NULL);
1305       loop = loop->next;
1306       curr = curr->next;
1307     }
1308
1309   return head;
1310 }
1311
1312
1313 /*------------------------------------------------------------------*/
1314 /* cleanUpBlock - cleansup the symbol table specified for all the   */
1315 /*                symbols in the given block                        */
1316 /*------------------------------------------------------------------*/
1317 void 
1318 cleanUpBlock (bucket ** table, int block)
1319 {
1320   int i;
1321   bucket *chain;
1322
1323   /* go thru the entire  table  */
1324   for (i = 0; i < 256; i++)
1325     {
1326       for (chain = table[i]; chain; chain = chain->next)
1327         {
1328           if (chain->block >= block)
1329             {
1330               deleteSym (table, chain->sym, chain->name);
1331             }
1332         }
1333     }
1334 }
1335
1336 /*------------------------------------------------------------------*/
1337 /* cleanUpLevel - cleansup the symbol table specified for all the   */
1338 /*                symbols in the given level                        */
1339 /*------------------------------------------------------------------*/
1340 void 
1341 cleanUpLevel (bucket ** table, int level)
1342 {
1343   int i;
1344   bucket *chain;
1345
1346   /* go thru the entire  table  */
1347   for (i = 0; i < 256; i++)
1348     {
1349       for (chain = table[i]; chain; chain = chain->next)
1350         {
1351           if (chain->level >= level)
1352             {
1353               deleteSym (table, chain->sym, chain->name);
1354             }
1355         }
1356     }
1357 }
1358
1359 /*------------------------------------------------------------------*/
1360 /* computeType - computes the resultant type from two types         */
1361 /*------------------------------------------------------------------*/
1362 sym_link *
1363 computeType (sym_link * type1, sym_link * type2)
1364 {
1365   sym_link *rType;
1366   sym_link *reType;
1367   sym_link *etype1 = getSpec (type1);
1368   sym_link *etype2 = getSpec (type2);
1369
1370   /* if one of them is a float then result is a float */
1371   /* here we assume that the types passed are okay */
1372   /* and can be cast to one another                */
1373   /* which ever is greater in size */
1374   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1375     rType = newFloatLink ();
1376   else
1377     /* if only one of them is a bit variable
1378        then the other one prevails */
1379   if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1380     rType = copyLinkChain (type2);
1381   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1382     rType = copyLinkChain (type1);
1383   else
1384     /* if one of them is a pointer then that
1385        prevails */
1386   if (IS_PTR (type1))
1387     rType = copyLinkChain (type1);
1388   else if (IS_PTR (type2))
1389     rType = copyLinkChain (type2);
1390   else if (getSize (type1) > getSize (type2))
1391     rType = copyLinkChain (type1);
1392   else
1393     rType = copyLinkChain (type2);
1394
1395   reType = getSpec (rType);
1396
1397   /* if either of them unsigned then make this unsigned */
1398   if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
1399     SPEC_USIGN (reType) = 1;
1400
1401   /* if result is a literal then make not so */
1402   if (IS_LITERAL (reType))
1403     SPEC_SCLS (reType) = S_REGISTER;
1404
1405   return rType;
1406 }
1407
1408 /*------------------------------------------------------------------*/
1409 /* checkType - will do type check return 1 if match                 */
1410 /*------------------------------------------------------------------*/
1411 int 
1412 checkType (sym_link * dest, sym_link * src)
1413 {
1414   if (!dest && !src)
1415     return 1;
1416
1417   if (dest && !src)
1418     return 0;
1419
1420   if (src && !dest)
1421     return 0;
1422
1423   /* if dest is a declarator then */
1424   if (IS_DECL (dest))
1425     {
1426       if (IS_DECL (src))
1427         {
1428           if (DCL_TYPE (src) == DCL_TYPE (dest))
1429             return checkType (dest->next, src->next);
1430           else if (IS_PTR (src) && IS_PTR (dest))
1431             return -1;
1432           else if (IS_PTR (dest) && IS_ARRAY (src))
1433             return -1;
1434           else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1435             return -1 * checkType (dest->next, src);
1436           else
1437             return 0;
1438         }
1439       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1440         return -1;
1441       else
1442         return 0;
1443     }
1444
1445   /* if one is a specifier and the other is not */
1446   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1447       (IS_SPEC (dest) && !IS_SPEC (src)))
1448     return 0;
1449
1450   /* if one of them is a void then ok */
1451   if (SPEC_NOUN (dest) == V_VOID &&
1452       SPEC_NOUN (src) != V_VOID)
1453     return -1;
1454
1455   if (SPEC_NOUN (dest) != V_VOID &&
1456       SPEC_NOUN (src) == V_VOID)
1457     return -1;
1458
1459   /* if they are both bitfields then if the lengths
1460      and starts don't match */
1461   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1462       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1463        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1464     return -1;
1465
1466   /* it is a specifier */
1467   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1468     {
1469       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1470           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1471           getSize (dest) == getSize (src))
1472         return 1;
1473       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1474         return -1;
1475       else
1476         return 0;
1477     }
1478   else if (IS_STRUCT (dest))
1479     {
1480       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1481         return 0;
1482       else
1483         return 1;
1484     }
1485   if (SPEC_LONG (dest) != SPEC_LONG (src))
1486     return -1;
1487
1488   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1489     return -2;
1490
1491   return 1;
1492 }
1493
1494 /*------------------------------------------------------------------*/
1495 /* inCalleeSaveList - return 1 if found in callee save list          */
1496 /*------------------------------------------------------------------*/
1497 bool 
1498 inCalleeSaveList (char *s)
1499 {
1500   int i;
1501
1502   for (i = 0; options.calleeSaves[i]; i++)
1503     if (strcmp (options.calleeSaves[i], s) == 0)
1504       return 1;
1505
1506   return 0;
1507 }
1508
1509 /*-----------------------------------------------------------------*/
1510 /* aggregateArgToPointer:  change an agggregate type function      */
1511 /*         argument to a pointer to that type.     */
1512 /*-----------------------------------------------------------------*/
1513 void 
1514 aggregateArgToPointer (value * val)
1515 {
1516   if (IS_AGGREGATE (val->type))
1517     {
1518       /* if this is a structure */
1519       /* then we need to add a new link */
1520       if (IS_STRUCT (val->type))
1521         {
1522           /* first lets add DECLARATOR type */
1523           sym_link *p = val->type;
1524
1525           werror (W_STRUCT_AS_ARG, val->name);
1526           val->type = newLink ();
1527           val->type->next = p;
1528         }
1529
1530       /* change to a pointer depending on the */
1531       /* storage class specified        */
1532       switch (SPEC_SCLS (val->etype))
1533         {
1534         case S_IDATA:
1535           DCL_TYPE (val->type) = IPOINTER;
1536           break;
1537         case S_PDATA:
1538           DCL_TYPE (val->type) = PPOINTER;
1539           break;
1540         case S_FIXED:
1541           if (TARGET_IS_DS390)
1542             {
1543               /* The AUTO and REGISTER classes should probably
1544                * also become generic pointers, but I haven't yet
1545                * devised a test case for that.
1546                */
1547               DCL_TYPE (val->type) = GPOINTER;
1548               break;
1549             }
1550           /* fall through! */
1551         case S_AUTO:
1552         case S_DATA:
1553         case S_REGISTER:
1554           DCL_TYPE (val->type) = POINTER;
1555           break;
1556         case S_CODE:
1557           DCL_TYPE (val->type) = CPOINTER;
1558           break;
1559         case S_XDATA:
1560           DCL_TYPE (val->type) = FPOINTER;
1561           break;
1562         case S_EEPROM:
1563           DCL_TYPE (val->type) = EEPPOINTER;
1564           break;
1565         default:
1566           DCL_TYPE (val->type) = GPOINTER;
1567         }
1568
1569       /* is there is a symbol associated then */
1570       /* change the type of the symbol as well */
1571       if (val->sym)
1572         {
1573           val->sym->type = copyLinkChain (val->type);
1574           val->sym->etype = getSpec (val->sym->type);
1575         }
1576     }
1577 }
1578 /*------------------------------------------------------------------*/
1579 /* checkFunction - does all kinds of check on a function            */
1580 /*------------------------------------------------------------------*/
1581 int 
1582 checkFunction (symbol * sym)
1583 {
1584   symbol *csym;
1585   value *exargs, *acargs;
1586   value *checkValue;
1587   int argCnt = 0;
1588
1589   if (getenv("DEBUG_SANITY")) {
1590     fprintf (stderr, "checkFunction: %s ", sym->name);
1591   }
1592
1593   /* make sure the type is complete and sane */
1594   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1595
1596   /* if not type then some kind of error */
1597   if (!sym->type)
1598     return 0;
1599
1600   /* if the function has no type then make it return int */
1601   if (!sym->type->next)
1602     sym->type->next = sym->etype = newIntLink ();
1603
1604   /* function cannot return aggregate */
1605   if (IS_AGGREGATE (sym->type->next))
1606     {
1607       werror (E_FUNC_AGGR, sym->name);
1608       return 0;
1609     }
1610
1611   /* function cannot return bit */
1612   if (IS_BITVAR (sym->type->next))
1613     {
1614       werror (E_FUNC_BIT, sym->name);
1615       return 0;
1616     }
1617
1618   /* check if this function is defined as calleeSaves
1619      then mark it as such */
1620   sym->calleeSave = inCalleeSaveList (sym->name);
1621
1622   /* if interrupt service routine  */
1623   /* then it cannot have arguments */
1624   if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
1625     {
1626       werror (E_INT_ARGS, sym->name);
1627       sym->args = NULL;
1628     }
1629
1630   if (!(csym = findSym (SymbolTab, sym, sym->name)))
1631     return 1;                   /* not defined nothing more to check  */
1632
1633   /* check if body already present */
1634   if (csym && csym->fbody)
1635     {
1636       werror (E_FUNC_BODY, sym->name);
1637       return 0;
1638     }
1639
1640   /* check the return value type   */
1641   if (checkType (csym->type, sym->type) <= 0)
1642     {
1643       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1644       werror (E_CONTINUE, "previous definition type ");
1645       printTypeChain (csym->type, stderr);
1646       fprintf (stderr, "\n");
1647       werror (E_CONTINUE, "current definition type ");
1648       printTypeChain (sym->type, stderr);
1649       fprintf (stderr, "\n");
1650       return 0;
1651     }
1652
1653   if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
1654     {
1655       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1656     }
1657
1658   if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
1659     {
1660       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1661     }
1662
1663   if (SPEC_NAKED (csym->etype) != SPEC_NAKED (sym->etype))
1664     {
1665       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1666     }
1667
1668   /* compare expected agrs with actual args */
1669   exargs = csym->args;
1670   acargs = sym->args;
1671
1672   /* for all the expected args do */
1673   for (argCnt = 1;
1674        exargs && acargs;
1675        exargs = exargs->next, acargs = acargs->next, argCnt++)
1676     {
1677       if (getenv("DEBUG_SANITY")) {
1678         fprintf (stderr, "checkFunction: %s ", exargs->name);
1679       }
1680       /* make sure the type is complete and sane */
1681       checkTypeSanity(exargs->etype, exargs->name);
1682
1683       /* If the actual argument is an array, any prototype
1684        * will have modified it to a pointer. Duplicate that
1685        * change here.
1686        */
1687       if (IS_AGGREGATE (acargs->type))
1688         {
1689           checkValue = copyValue (acargs);
1690           aggregateArgToPointer (checkValue);
1691         }
1692       else
1693         {
1694           checkValue = acargs;
1695         }
1696
1697       if (checkType (exargs->type, checkValue->type) <= 0)
1698         {
1699           werror (E_ARG_TYPE, argCnt);
1700           return 0;
1701         }
1702     }
1703
1704   /* if one them ended we have a problem */
1705   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1706       (!exargs && acargs && !IS_VOID (acargs->type)))
1707     werror (E_ARG_COUNT);
1708
1709   /* replace with this defition */
1710   sym->cdef = csym->cdef;
1711   deleteSym (SymbolTab, csym, csym->name);
1712   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1713   if (IS_EXTERN (csym->etype) && !
1714       IS_EXTERN (sym->etype))
1715     {
1716       addSet (&publics, sym);
1717     }
1718   return 1;
1719 }
1720
1721 /*-----------------------------------------------------------------*/
1722 /* processFuncArgs - does some processing with function args       */
1723 /*-----------------------------------------------------------------*/
1724 void 
1725 processFuncArgs (symbol * func, int ignoreName)
1726 {
1727   value *val;
1728   int pNum = 1;
1729
1730   /* if this function has variable argument list */
1731   /* then make the function a reentrant one    */
1732   if (func->hasVargs)
1733     SPEC_RENT (func->etype) = 1;
1734
1735   /* check if this function is defined as calleeSaves
1736      then mark it as such */
1737   func->calleeSave = inCalleeSaveList (func->name);
1738
1739   val = func->args;             /* loop thru all the arguments   */
1740
1741   /* if it is void then remove parameters */
1742   if (val && IS_VOID (val->type))
1743     {
1744       func->args = NULL;
1745       return;
1746     }
1747
1748   /* reset regparm for the port */
1749   (*port->reset_regparms) ();
1750   /* if any of the arguments is an aggregate */
1751   /* change it to pointer to the same type */
1752   while (val)
1753     {
1754       /* mark it as a register parameter if
1755          the function does not have VA_ARG
1756          and as port dictates */
1757       if (!func->hasVargs &&
1758           (*port->reg_parm) (val->type))
1759         {
1760           SPEC_REGPARM (val->etype) = 1;
1761         }
1762
1763       if (IS_AGGREGATE (val->type))
1764         {
1765           aggregateArgToPointer (val);
1766         }
1767       val = val->next;
1768       pNum++;
1769     }
1770
1771   /* if this is an internal generated function call */
1772   if (func->cdef) {
1773     /* ignore --stack-auto for this one, we don't know how it is compiled */
1774     /* simply trust on --int-long-reent or --float-reent */
1775     if (IS_RENT(func->etype)) {
1776       return;
1777     }
1778   } else {
1779     /* if this function is reentrant or */
1780     /* automatics r 2b stacked then nothing */
1781     if (IS_RENT (func->etype) || options.stackAuto)
1782       return;
1783   }
1784
1785   val = func->args;
1786   pNum = 1;
1787   while (val)
1788     {
1789
1790       /* if a symbolname is not given  */
1791       /* synthesize a variable name */
1792       if (!val->sym)
1793         {
1794
1795           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1796           val->sym = newSymbol (val->name, 1);
1797           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1798           val->sym->type = copyLinkChain (val->type);
1799           val->sym->etype = getSpec (val->sym->type);
1800           val->sym->_isparm = 1;
1801           strcpy (val->sym->rname, val->name);
1802           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1803             SPEC_STAT (func->etype);
1804           addSymChain (val->sym);
1805
1806         }
1807       else                      /* symbol name given create synth name */
1808         {
1809
1810           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1811           strcpy (val->sym->rname, val->name);
1812           val->sym->_isparm = 1;
1813           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1814             (options.model != MODEL_SMALL ? xdata : data);
1815           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1816             SPEC_STAT (func->etype);
1817         }
1818       val = val->next;
1819     }
1820 }
1821
1822 /*-----------------------------------------------------------------*/
1823 /* isSymbolEqual - compares two symbols return 1 if they match     */
1824 /*-----------------------------------------------------------------*/
1825 int 
1826 isSymbolEqual (symbol * dest, symbol * src)
1827 {
1828   /* if pointers match then equal */
1829   if (dest == src)
1830     return 1;
1831
1832   /* if one of them is null then don't match */
1833   if (!dest || !src)
1834     return 0;
1835
1836   /* if both of them have rname match on rname */
1837   if (dest->rname[0] && src->rname[0])
1838     return (!strcmp (dest->rname, src->rname));
1839
1840   /* otherwise match on name */
1841   return (!strcmp (dest->name, src->name));
1842 }
1843
1844 void PT(sym_link *type)
1845 {
1846         printTypeChain(type,0);
1847 }
1848 /*-----------------------------------------------------------------*/
1849 /* printTypeChain - prints the type chain in human readable form   */
1850 /*-----------------------------------------------------------------*/
1851 void 
1852 printTypeChain (sym_link * type, FILE * of)
1853 {
1854   int nlr = 0;
1855
1856   if (!of)
1857     {
1858       of = stdout;
1859       nlr = 1;
1860     }
1861
1862   while (type)
1863     {
1864       if (IS_DECL (type))
1865         {
1866           if (DCL_PTR_VOLATILE(type)) {
1867             fprintf (of, "volatile ");
1868           }
1869           switch (DCL_TYPE (type))
1870             {
1871             case FUNCTION:
1872               fprintf (of, "function ");
1873               break;
1874             case GPOINTER:
1875               fprintf (of, "_generic * ");
1876               if (DCL_PTR_CONST (type))
1877                 fprintf (of, "const ");
1878               break;
1879             case CPOINTER:
1880               fprintf (of, "_code * ");
1881               if (DCL_PTR_CONST (type))
1882                 fprintf (of, "const ");
1883               break;
1884             case FPOINTER:
1885               fprintf (of, "_far * ");
1886               if (DCL_PTR_CONST (type))
1887                 fprintf (of, "const ");
1888               break;
1889             case EEPPOINTER:
1890               fprintf (of, "_eeprom * ");
1891               if (DCL_PTR_CONST (type))
1892                 fprintf (of, "const ");
1893               break;
1894
1895             case POINTER:
1896               fprintf (of, "_near * ");
1897               if (DCL_PTR_CONST (type))
1898                 fprintf (of, "const ");
1899               break;
1900             case IPOINTER:
1901               fprintf (of, "_idata *");
1902               if (DCL_PTR_CONST (type))
1903                 fprintf (of, "const ");
1904               break;
1905             case PPOINTER:
1906               fprintf (of, "_pdata *");
1907               if (DCL_PTR_CONST (type))
1908                 fprintf (of, "const ");
1909               break;
1910             case UPOINTER:
1911               fprintf (of, " _unkown *");
1912               if (DCL_PTR_CONST (type))
1913                 fprintf (of, "const ");
1914               break;
1915             case ARRAY:
1916               fprintf (of, "array of ");
1917               break;
1918             }
1919         }
1920       else
1921         {
1922           if (SPEC_VOLATILE (type))
1923             fprintf (of, "volatile ");
1924           if (SPEC_USIGN (type))
1925             fprintf (of, "unsigned ");
1926           if (SPEC_CONST (type))
1927             fprintf (of, "const ");
1928
1929           switch (SPEC_NOUN (type))
1930             {
1931             case V_INT:
1932               if (IS_LONG (type))
1933                 fprintf (of, "long ");
1934               fprintf (of, "int ");
1935               break;
1936
1937             case V_CHAR:
1938               fprintf (of, "char ");
1939               break;
1940
1941             case V_VOID:
1942               fprintf (of, "void ");
1943               break;
1944
1945             case V_FLOAT:
1946               fprintf (of, "float ");
1947               break;
1948
1949             case V_STRUCT:
1950               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1951               break;
1952
1953             case V_SBIT:
1954               fprintf (of, "sbit ");
1955               break;
1956
1957             case V_BIT:
1958               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1959               break;
1960
1961             case V_DOUBLE:
1962               fprintf (of, "double ");
1963               break;
1964
1965             default:
1966               fprintf (of, "unknown type ");
1967               break;
1968             }
1969         }
1970       type = type->next;
1971     }
1972   if (nlr)
1973     fprintf (of, "\n");
1974 }
1975
1976 /*-----------------------------------------------------------------*/
1977 /* cdbTypeInfo - print the type information for debugger           */
1978 /*-----------------------------------------------------------------*/
1979 void 
1980 cdbTypeInfo (sym_link * type, FILE * of)
1981 {
1982   fprintf (of, "{%d}", getSize (type));
1983   while (type)
1984     {
1985       if (IS_DECL (type))
1986         {
1987           switch (DCL_TYPE (type))
1988             {
1989             case FUNCTION:
1990               fprintf (of, "DF,");
1991               break;
1992             case GPOINTER:
1993               fprintf (of, "DG,");
1994               break;
1995             case CPOINTER:
1996               fprintf (of, "DC,");
1997               break;
1998             case FPOINTER:
1999               fprintf (of, "DX,");
2000               break;
2001             case POINTER:
2002               fprintf (of, "DD,");
2003               break;
2004             case IPOINTER:
2005               fprintf (of, "DI,");
2006               break;
2007             case PPOINTER:
2008               fprintf (of, "DP,");
2009               break;
2010             case EEPPOINTER:
2011               fprintf (of, "DA,");
2012               break;
2013             case ARRAY:
2014               fprintf (of, "DA%d,", DCL_ELEM (type));
2015               break;
2016             default:
2017               break;
2018             }
2019         }
2020       else
2021         {
2022           switch (SPEC_NOUN (type))
2023             {
2024             case V_INT:
2025               if (IS_LONG (type))
2026                 fprintf (of, "SL");
2027               else
2028                 fprintf (of, "SI");
2029               break;
2030
2031             case V_CHAR:
2032               fprintf (of, "SC");
2033               break;
2034
2035             case V_VOID:
2036               fprintf (of, "SV");
2037               break;
2038
2039             case V_FLOAT:
2040               fprintf (of, "SF");
2041               break;
2042
2043             case V_STRUCT:
2044               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2045               break;
2046
2047             case V_SBIT:
2048               fprintf (of, "SX");
2049               break;
2050
2051             case V_BIT:
2052               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2053               break;
2054
2055             default:
2056               break;
2057             }
2058           fputs (":", of);
2059           if (SPEC_USIGN (type))
2060             fputs ("U", of);
2061           else
2062             fputs ("S", of);
2063         }
2064       type = type->next;
2065     }
2066 }
2067 /*-----------------------------------------------------------------*/
2068 /* cdbSymbol - prints a symbol & its type information for debugger */
2069 /*-----------------------------------------------------------------*/
2070 void 
2071 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2072 {
2073   memmap *map;
2074
2075   if (!sym)
2076     return;
2077   if (!of)
2078     of = stdout;
2079
2080   if (isFunc)
2081     fprintf (of, "F:");
2082   else
2083     fprintf (of, "S:");         /* symbol record */
2084   /* if this is not a structure symbol then
2085      we need to figure out the scope information */
2086   if (!isStructSym)
2087     {
2088       if (!sym->level)
2089         {
2090           /* global */
2091           if (IS_STATIC (sym->etype))
2092             fprintf (of, "F%s$", moduleName);   /* scope is file */
2093           else
2094             fprintf (of, "G$"); /* scope is global */
2095         }
2096       else
2097         /* symbol is local */
2098         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2099     }
2100   else
2101     fprintf (of, "S$");         /* scope is structure */
2102
2103   /* print the name, & mangled name */
2104   fprintf (of, "%s$%d$%d(", sym->name,
2105            sym->level, sym->block);
2106
2107   cdbTypeInfo (sym->type, of);
2108   fprintf (of, "),");
2109
2110   /* print the address space */
2111   map = SPEC_OCLS (sym->etype);
2112   fprintf (of, "%c,%d,%d",
2113            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2114
2115   /* if assigned to registers then output register names */
2116   /* if this is a function then print
2117      if is it an interrupt routine & interrupt number
2118      and the register bank it is using */
2119   if (isFunc)
2120     fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
2121              SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
2122   /* alternate location to find this symbol @ : eg registers
2123      or spillication */
2124
2125   if (!isStructSym)
2126     fprintf (of, "\n");
2127 }
2128
2129 /*-----------------------------------------------------------------*/
2130 /* cdbStruct - print a structure for debugger                      */
2131 /*-----------------------------------------------------------------*/
2132 void 
2133 cdbStruct (structdef * sdef, int block, FILE * of,
2134            int inStruct, char *tag)
2135 {
2136   symbol *sym;
2137
2138   fprintf (of, "T:");
2139   /* if block # then must have function scope */
2140   fprintf (of, "F%s$", moduleName);
2141   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2142   for (sym = sdef->fields; sym; sym = sym->next)
2143     {
2144       fprintf (of, "({%d}", sym->offset);
2145       cdbSymbol (sym, of, TRUE, FALSE);
2146       fprintf (of, ")");
2147     }
2148   fprintf (of, "]");
2149   if (!inStruct)
2150     fprintf (of, "\n");
2151 }
2152
2153 /*------------------------------------------------------------------*/
2154 /* cdbStructBlock - calls struct printing for a blcks               */
2155 /*------------------------------------------------------------------*/
2156 void 
2157 cdbStructBlock (int block, FILE * of)
2158 {
2159   int i;
2160   bucket **table = StructTab;
2161   bucket *chain;
2162   wassert (of);
2163
2164   /* go thru the entire  table  */
2165   for (i = 0; i < 256; i++)
2166     {
2167       for (chain = table[i]; chain; chain = chain->next)
2168         {
2169           if (chain->block >= block)
2170             {
2171               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2172             }
2173         }
2174     }
2175 }
2176
2177 /*-----------------------------------------------------------------*/
2178 /* powof2 - returns power of two for the number if number is pow 2 */
2179 /*-----------------------------------------------------------------*/
2180 int 
2181 powof2 (unsigned long num)
2182 {
2183   int nshifts = 0;
2184   int n1s = 0;
2185
2186   while (num)
2187     {
2188       if (num & 1)
2189         n1s++;
2190       num >>= 1;
2191       nshifts++;
2192     }
2193
2194   if (n1s > 1 || nshifts == 0)
2195     return 0;
2196   return nshifts - 1;
2197 }
2198
2199 symbol *__fsadd;
2200 symbol *__fssub;
2201 symbol *__fsmul;
2202 symbol *__fsdiv;
2203 symbol *__fseq;
2204 symbol *__fsneq;
2205 symbol *__fslt;
2206 symbol *__fslteq;
2207 symbol *__fsgt;
2208 symbol *__fsgteq;
2209
2210 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2211 symbol *__muldiv[3][3][2];
2212 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2213 sym_link *__multypes[3][2];
2214 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2215 symbol *__conv[2][3][2];
2216
2217 sym_link *floatType;
2218
2219 static void 
2220 _makeRegParam (symbol * sym)
2221 {
2222   value *val;
2223
2224   val = sym->args;              /* loop thru all the arguments   */
2225
2226   /* reset regparm for the port */
2227   (*port->reset_regparms) ();
2228   while (val)
2229     {
2230       SPEC_REGPARM (val->etype) = 1;
2231       val = val->next;
2232     }
2233 }
2234
2235 /*-----------------------------------------------------------------*/
2236 /* initCSupport - create functions for C support routines          */
2237 /*-----------------------------------------------------------------*/
2238 void 
2239 initCSupport ()
2240 {
2241   const char *smuldivmod[] =
2242   {
2243     "mul", "div", "mod"
2244   };
2245   const char *sbwd[] =
2246   {
2247     "char", "int", "long"
2248   };
2249   const char *ssu[] =
2250   {
2251     "s", "u"
2252   };
2253
2254   int bwd, su, muldivmod, tofrom;
2255
2256   floatType = newFloatLink ();
2257
2258   for (bwd = 0; bwd < 3; bwd++)
2259     {
2260       sym_link *l;
2261       switch (bwd)
2262         {
2263         case 0:
2264           l = newCharLink ();
2265           break;
2266         case 1:
2267           l = newIntLink ();
2268           break;
2269         case 2:
2270           l = newLongLink ();
2271           break;
2272         default:
2273           assert (0);
2274         }
2275       __multypes[bwd][0] = l;
2276       __multypes[bwd][1] = copyLinkChain (l);
2277       SPEC_USIGN (__multypes[bwd][1]) = 1;
2278     }
2279
2280   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2281   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2282   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2283   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2284   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2285   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2286   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2287   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2288   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2289   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2290
2291   for (tofrom = 0; tofrom < 2; tofrom++)
2292     {
2293       for (bwd = 0; bwd < 3; bwd++)
2294         {
2295           for (su = 0; su < 2; su++)
2296             {
2297               if (tofrom)
2298                 {
2299                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2300                   __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2301                 }
2302               else
2303                 {
2304                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2305                   __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2306                 }
2307             }
2308         }
2309     }
2310
2311   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2312     {
2313       for (bwd = 0; bwd < 3; bwd++)
2314         {
2315           for (su = 0; su < 2; su++)
2316             {
2317               sprintf (buffer, "_%s%s%s",
2318                        smuldivmod[muldivmod],
2319                        ssu[su],
2320                        sbwd[bwd]);
2321               __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2322               SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2323               if (bwd < port->muldiv.force_reg_param_below)
2324                 _makeRegParam (__muldiv[muldivmod][bwd][su]);
2325             }
2326         }
2327     }
2328 }