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