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