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