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