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