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