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