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