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