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