small reg bank fix
[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;
1456           }
1457           if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1458             return compareType (dest->next, src);
1459           return 0;
1460         }
1461       else if (IS_PTR (dest) && IS_INTEGRAL (src))
1462         return -1;
1463       else
1464         return 0;
1465     }
1466
1467   /* if one is a specifier and the other is not */
1468   if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1469       (IS_SPEC (dest) && !IS_SPEC (src)))
1470     return 0;
1471
1472   /* if one of them is a void then ok */
1473   if (SPEC_NOUN (dest) == V_VOID &&
1474       SPEC_NOUN (src) != V_VOID)
1475     return -1;
1476
1477   if (SPEC_NOUN (dest) != V_VOID &&
1478       SPEC_NOUN (src) == V_VOID)
1479     return -1;
1480
1481   /* if they are both bitfields then if the lengths
1482      and starts don't match */
1483   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1484       (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1485        SPEC_BSTR (dest) != SPEC_BSTR (src)))
1486     return -1;
1487
1488   /* it is a specifier */
1489   if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1490     {
1491       if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1492           IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1493           getSize (dest) == getSize (src))
1494         return 1;
1495       else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1496         return -1;
1497       else
1498         return 0;
1499     }
1500   else if (IS_STRUCT (dest))
1501     {
1502       if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1503         return 0;
1504       else
1505         return 1;
1506     }
1507   if (SPEC_LONG (dest) != SPEC_LONG (src))
1508     return -1;
1509
1510   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1511     return -1;
1512
1513   return 1;
1514 }
1515
1516 /*------------------------------------------------------------------*/
1517 /* inCalleeSaveList - return 1 if found in callee save list          */
1518 /*------------------------------------------------------------------*/
1519 bool 
1520 inCalleeSaveList (char *s)
1521 {
1522   int i;
1523
1524   for (i = 0; options.calleeSaves[i]; i++)
1525     if (strcmp (options.calleeSaves[i], s) == 0)
1526       return 1;
1527
1528   return 0;
1529 }
1530
1531 /*-----------------------------------------------------------------*/
1532 /* aggregateToPointer:  change an agggregate type function      */
1533 /*         argument to a pointer to that type.     */
1534 /*-----------------------------------------------------------------*/
1535 value *
1536 aggregateToPointer (value * val)
1537 {
1538   if (IS_AGGREGATE (val->type))
1539     {
1540       /* if this is a structure */
1541       /* then we need to add a new link */
1542       if (IS_STRUCT (val->type))
1543         {
1544           /* first lets add DECLARATOR type */
1545           sym_link *p = val->type;
1546
1547           werror (W_STRUCT_AS_ARG, val->name);
1548           val->type = newLink ();
1549           val->type->next = p;
1550         }
1551
1552       /* change to a pointer depending on the */
1553       /* storage class specified        */
1554       switch (SPEC_SCLS (val->etype))
1555         {
1556         case S_IDATA:
1557           DCL_TYPE (val->type) = IPOINTER;
1558           break;
1559         case S_PDATA:
1560           DCL_TYPE (val->type) = PPOINTER;
1561           break;
1562         case S_FIXED:
1563           if (TARGET_IS_DS390)
1564             {
1565               /* The AUTO and REGISTER classes should probably
1566                * also become generic pointers, but I haven't yet
1567                * devised a test case for that.
1568                */
1569               DCL_TYPE (val->type) = GPOINTER;
1570               break;
1571             }
1572           if (options.model==MODEL_LARGE) {
1573             DCL_TYPE (val->type) = FPOINTER;
1574             break;
1575           }
1576           /* fall through! */
1577         case S_AUTO:
1578         case S_DATA:
1579         case S_REGISTER:
1580           DCL_TYPE (val->type) = POINTER;
1581           break;
1582         case S_CODE:
1583           DCL_TYPE (val->type) = CPOINTER;
1584           break;
1585         case S_XDATA:
1586           DCL_TYPE (val->type) = FPOINTER;
1587           break;
1588         case S_EEPROM:
1589           DCL_TYPE (val->type) = EEPPOINTER;
1590           break;
1591         default:
1592           DCL_TYPE (val->type) = GPOINTER;
1593         }
1594       
1595       /* is there is a symbol associated then */
1596       /* change the type of the symbol as well */
1597       if (val->sym)
1598         {
1599           val->sym->type = copyLinkChain (val->type);
1600           val->sym->etype = getSpec (val->sym->type);
1601         }
1602     }
1603   return val;
1604 }
1605 /*------------------------------------------------------------------*/
1606 /* checkFunction - does all kinds of check on a function            */
1607 /*------------------------------------------------------------------*/
1608 int 
1609 checkFunction (symbol * sym, symbol *csym)
1610 {
1611   value *exargs, *acargs;
1612   value *checkValue;
1613   int argCnt = 0;
1614
1615   if (getenv("DEBUG_SANITY")) {
1616     fprintf (stderr, "checkFunction: %s ", sym->name);
1617   }
1618
1619   /* make sure the type is complete and sane */
1620   checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
1621
1622   /* if not type then some kind of error */
1623   if (!sym->type)
1624     return 0;
1625
1626   /* if the function has no type then make it return int */
1627   if (!sym->type->next)
1628     sym->type->next = sym->etype = newIntLink ();
1629
1630   /* function cannot return aggregate */
1631   if (IS_AGGREGATE (sym->type->next))
1632     {
1633       werror (E_FUNC_AGGR, sym->name);
1634       return 0;
1635     }
1636
1637   /* function cannot return bit */
1638   if (IS_BITVAR (sym->type->next))
1639     {
1640       werror (E_FUNC_BIT, sym->name);
1641       return 0;
1642     }
1643
1644   /* check if this function is defined as calleeSaves
1645      then mark it as such */
1646     FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name);
1647
1648   /* if interrupt service routine  */
1649   /* then it cannot have arguments */
1650   if (IFFUNC_ARGS(sym->type) && FUNC_ISISR (sym->type))
1651     {
1652       if (!IS_VOID(FUNC_ARGS(sym->type)->type)) {
1653         werror (E_INT_ARGS, sym->name);
1654         FUNC_ARGS(sym->type)=NULL;
1655       }
1656     }
1657
1658   if (!csym && !(csym = findSym (SymbolTab, sym, sym->name)))
1659     return 1;                   /* not defined nothing more to check  */
1660
1661   /* check if body already present */
1662   if (csym && IFFUNC_HASBODY(csym->type))
1663     {
1664       werror (E_FUNC_BODY, sym->name);
1665       return 0;
1666     }
1667
1668   /* check the return value type   */
1669   if (compareType (csym->type, sym->type) <= 0)
1670     {
1671       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1672       werror (W_CONTINUE, "previous definition type ");
1673       printTypeChain (csym->type, stderr);
1674       fprintf (stderr, "\n");
1675       werror (W_CONTINUE, "current definition type ");
1676       printTypeChain (sym->type, stderr);
1677       fprintf (stderr, "\n");
1678       return 0;
1679     }
1680
1681   if (FUNC_ISISR (csym->type) != FUNC_ISISR (sym->type))
1682     {
1683       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1684     }
1685
1686   if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type))
1687     {
1688       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1689     }
1690
1691   if (IFFUNC_ISNAKED (csym->type) != IFFUNC_ISNAKED (sym->type))
1692     {
1693       werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
1694     }
1695
1696   /* compare expected args with actual args */
1697   exargs = FUNC_ARGS(csym->type);
1698   acargs = FUNC_ARGS(sym->type);
1699
1700   /* for all the expected args do */
1701   for (argCnt = 1;
1702        exargs && acargs;
1703        exargs = exargs->next, acargs = acargs->next, argCnt++)
1704     {
1705       if (getenv("DEBUG_SANITY")) {
1706         fprintf (stderr, "checkFunction: %s ", exargs->name);
1707       }
1708       /* make sure the type is complete and sane */
1709       checkTypeSanity(exargs->etype, exargs->name);
1710
1711       /* If the actual argument is an array, any prototype
1712        * will have modified it to a pointer. Duplicate that
1713        * change here.
1714        */
1715       if (IS_AGGREGATE (acargs->type))
1716         {
1717           checkValue = copyValue (acargs);
1718           aggregateToPointer (checkValue);
1719         }
1720       else
1721         {
1722           checkValue = acargs;
1723         }
1724
1725       if (compareType (exargs->type, checkValue->type) <= 0)
1726         {
1727           werror (E_ARG_TYPE, argCnt);
1728           return 0;
1729         }
1730     }
1731
1732   /* if one them ended we have a problem */
1733   if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1734       (!exargs && acargs && !IS_VOID (acargs->type)))
1735     werror (E_ARG_COUNT);
1736
1737   /* replace with this defition */
1738   sym->cdef = csym->cdef;
1739   deleteSym (SymbolTab, csym, csym->name);
1740   addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
1741   if (IS_EXTERN (csym->etype) && !
1742       IS_EXTERN (sym->etype))
1743     {
1744       addSet (&publics, sym);
1745     }
1746   return 1;
1747 }
1748
1749 /*-----------------------------------------------------------------*/
1750 /* processFuncArgs - does some processing with function args       */
1751 /*-----------------------------------------------------------------*/
1752 void 
1753 processFuncArgs (symbol * func, int ignoreName)
1754 {
1755   value *val;
1756   int pNum = 1;
1757
1758   /* if this function has variable argument list */
1759   /* then make the function a reentrant one    */
1760   if (IFFUNC_HASVARARGS(func->type))
1761     FUNC_ISREENT(func->type)=1;
1762
1763   /* check if this function is defined as calleeSaves
1764      then mark it as such */
1765   FUNC_CALLEESAVES(func->type) = inCalleeSaveList (func->name);
1766
1767   /* loop thru all the arguments   */
1768   val = FUNC_ARGS(func->type);
1769
1770   /* if it is void then remove parameters */
1771   if (val && IS_VOID (val->type))
1772     {
1773       FUNC_ARGS(func->type) = NULL;
1774       return;
1775     }
1776
1777   /* reset regparm for the port */
1778   (*port->reset_regparms) ();
1779   /* if any of the arguments is an aggregate */
1780   /* change it to pointer to the same type */
1781   while (val)
1782     {
1783       /* mark it as a register parameter if
1784          the function does not have VA_ARG
1785          and as port dictates */
1786       if (!IFFUNC_HASVARARGS(func->type) &&
1787           (*port->reg_parm) (val->type))
1788         {
1789           SPEC_REGPARM (val->etype) = 1;
1790         }
1791
1792       if (IS_AGGREGATE (val->type))
1793         {
1794           aggregateToPointer (val);
1795         }
1796       val = val->next;
1797       pNum++;
1798     }
1799
1800   /* if this is an internal generated function call */
1801   if (func->cdef) {
1802     /* ignore --stack-auto for this one, we don't know how it is compiled */
1803     /* simply trust on --int-long-reent or --float-reent */
1804     if (IFFUNC_ISREENT(func->type)) {
1805       return;
1806     }
1807   } else {
1808     /* if this function is reentrant or */
1809     /* automatics r 2b stacked then nothing */
1810     if (IFFUNC_ISREENT (func->type) || options.stackAuto)
1811       return;
1812   }
1813
1814   val = FUNC_ARGS(func->type);
1815   pNum = 1;
1816   while (val)
1817     {
1818
1819       /* if a symbolname is not given  */
1820       /* synthesize a variable name */
1821       if (!val->sym)
1822         {
1823
1824           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1825           val->sym = newSymbol (val->name, 1);
1826           SPEC_OCLS (val->etype) = port->mem.default_local_map;
1827           val->sym->type = copyLinkChain (val->type);
1828           val->sym->etype = getSpec (val->sym->type);
1829           val->sym->_isparm = 1;
1830           strcpy (val->sym->rname, val->name);
1831           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1832             SPEC_STAT (func->etype);
1833           addSymChain (val->sym);
1834
1835         }
1836       else                      /* symbol name given create synth name */
1837         {
1838
1839           sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1840           strcpy (val->sym->rname, val->name);
1841           val->sym->_isparm = 1;
1842           SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1843             (options.model != MODEL_SMALL ? xdata : data);
1844           SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1845             SPEC_STAT (func->etype);
1846         }
1847       val = val->next;
1848     }
1849 }
1850
1851 /*-----------------------------------------------------------------*/
1852 /* isSymbolEqual - compares two symbols return 1 if they match     */
1853 /*-----------------------------------------------------------------*/
1854 int 
1855 isSymbolEqual (symbol * dest, symbol * src)
1856 {
1857   /* if pointers match then equal */
1858   if (dest == src)
1859     return 1;
1860
1861   /* if one of them is null then don't match */
1862   if (!dest || !src)
1863     return 0;
1864
1865   /* if both of them have rname match on rname */
1866   if (dest->rname[0] && src->rname[0])
1867     return (!strcmp (dest->rname, src->rname));
1868
1869   /* otherwise match on name */
1870   return (!strcmp (dest->name, src->name));
1871 }
1872
1873 void PT(sym_link *type)
1874 {
1875         printTypeChain(type,0);
1876 }
1877 /*-----------------------------------------------------------------*/
1878 /* printTypeChain - prints the type chain in human readable form   */
1879 /*-----------------------------------------------------------------*/
1880 void
1881 printTypeChain (sym_link * start, FILE * of)
1882 {
1883   int nlr = 0;
1884   sym_link * type, * search;
1885
1886   if (!of)
1887     {
1888       of = stdout;
1889       nlr = 1;
1890     }
1891
1892   if (start==NULL) {
1893     fprintf (of, "**err**");
1894     return;
1895   }
1896
1897   /* print the chain as it is written in the source: */
1898   /* start with the last entry                       */
1899   for (type = start; type && type->next; type = type->next)
1900     ;
1901   while (type)
1902     {
1903       if (IS_DECL (type))
1904         {
1905           if (DCL_PTR_VOLATILE (type)) {
1906             fprintf (of, "volatile ");
1907           }
1908           switch (DCL_TYPE (type))
1909             {
1910             case FUNCTION:
1911               fprintf (of, "function ");
1912               break;
1913             case GPOINTER:
1914               if (DCL_PTR_CONST (type))
1915                 fprintf (of, "const ");
1916               fprintf (of, "* generic ");
1917               break;
1918             case CPOINTER:
1919               if (DCL_PTR_CONST (type))
1920                 fprintf (of, "const ");
1921               fprintf (of, "* code ");
1922               break;
1923             case FPOINTER:
1924               if (DCL_PTR_CONST (type))
1925                 fprintf (of, "const ");
1926               fprintf (of, "* xdata ");
1927               break;
1928             case EEPPOINTER:
1929               if (DCL_PTR_CONST (type))
1930                 fprintf (of, "const ");
1931               fprintf (of, "* eeprom ");
1932               break;
1933
1934             case POINTER:
1935               if (DCL_PTR_CONST (type))
1936                 fprintf (of, "const ");
1937               fprintf (of, "* near ");
1938               break;
1939             case IPOINTER:
1940               if (DCL_PTR_CONST (type))
1941                 fprintf (of, "const ");
1942               fprintf (of, "* idata ");
1943               break;
1944             case PPOINTER:
1945               if (DCL_PTR_CONST (type))
1946                 fprintf (of, "const ");
1947               fprintf (of, "* pdata ");
1948               break;
1949             case UPOINTER:
1950               if (DCL_PTR_CONST (type))
1951                 fprintf (of, "const ");
1952               fprintf (of, "* unkown ");
1953               break;
1954             case ARRAY:
1955               fprintf (of, "[] ");
1956               break;
1957             }
1958         }
1959       else
1960         {
1961           switch (SPEC_SCLS(type)) 
1962             {
1963             case S_DATA: fprintf (of, "data "); break;
1964             case S_XDATA: fprintf (of, "xdata "); break;
1965             case S_SFR: fprintf (of, "sfr "); break;
1966             case S_SBIT: fprintf (of, "sbit "); break;
1967             case S_CODE: fprintf (of, "code "); break;
1968             case S_IDATA: fprintf (of, "idata "); break;
1969             case S_PDATA: fprintf (of, "pdata "); break;
1970             case S_LITERAL: fprintf (of, "literal "); break;
1971             case S_STACK: fprintf (of, "stack "); break;
1972             case S_XSTACK: fprintf (of, "xstack "); break;
1973             case S_BIT: fprintf (of, "bit "); break;
1974             case S_EEPROM: fprintf (of, "eeprom "); break;
1975             default: break;
1976             }
1977
1978           if (SPEC_VOLATILE (type))
1979             fprintf (of, "volatile ");
1980           if (SPEC_USIGN (type))
1981             fprintf (of, "unsigned ");
1982           if (SPEC_CONST (type))
1983             fprintf (of, "const ");
1984
1985           switch (SPEC_NOUN (type))
1986             {
1987             case V_INT:
1988               if (IS_LONG (type))
1989                 fprintf (of, "long ");
1990               fprintf (of, "int");
1991               break;
1992
1993             case V_CHAR:
1994               fprintf (of, "char");
1995               break;
1996
1997             case V_VOID:
1998               fprintf (of, "void");
1999               break;
2000
2001             case V_FLOAT:
2002               fprintf (of, "float");
2003               break;
2004
2005             case V_STRUCT:
2006               fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
2007               break;
2008
2009             case V_SBIT:
2010               fprintf (of, "sbit");
2011               break;
2012
2013             case V_BIT:
2014               fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
2015               break;
2016
2017             case V_DOUBLE:
2018               fprintf (of, "double");
2019               break;
2020
2021             default:
2022               fprintf (of, "unknown type");
2023               break;
2024             }
2025         }
2026         /* search entry in list before "type" */
2027     for (search = start; search && search->next != type;)
2028        search = search->next;
2029     type = search;
2030     if (type)
2031       fputc (' ', of);
2032     }
2033   if (nlr)
2034     fprintf (of, "\n");
2035 }
2036
2037 /*-----------------------------------------------------------------*/
2038 /* cdbTypeInfo - print the type information for debugger           */
2039 /*-----------------------------------------------------------------*/
2040 void
2041 cdbTypeInfo (sym_link * type, FILE * of)
2042 {
2043   fprintf (of, "{%d}", getSize (type));
2044   while (type)
2045     {
2046       if (IS_DECL (type))
2047         {
2048           switch (DCL_TYPE (type))
2049             {
2050             case FUNCTION:
2051               fprintf (of, "DF,");
2052               break;
2053             case GPOINTER:
2054               fprintf (of, "DG,");
2055               break;
2056             case CPOINTER:
2057               fprintf (of, "DC,");
2058               break;
2059             case FPOINTER:
2060               fprintf (of, "DX,");
2061               break;
2062             case POINTER:
2063               fprintf (of, "DD,");
2064               break;
2065             case IPOINTER:
2066               fprintf (of, "DI,");
2067               break;
2068             case PPOINTER:
2069               fprintf (of, "DP,");
2070               break;
2071             case EEPPOINTER:
2072               fprintf (of, "DA,");
2073               break;
2074             case ARRAY:
2075               fprintf (of, "DA%d,", DCL_ELEM (type));
2076               break;
2077             default:
2078               break;
2079             }
2080         }
2081       else
2082         {
2083           switch (SPEC_NOUN (type))
2084             {
2085             case V_INT:
2086               if (IS_LONG (type))
2087                 fprintf (of, "SL");
2088               else
2089                 fprintf (of, "SI");
2090               break;
2091
2092             case V_CHAR:
2093               fprintf (of, "SC");
2094               break;
2095
2096             case V_VOID:
2097               fprintf (of, "SV");
2098               break;
2099
2100             case V_FLOAT:
2101               fprintf (of, "SF");
2102               break;
2103
2104             case V_STRUCT:
2105               fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
2106               break;
2107
2108             case V_SBIT:
2109               fprintf (of, "SX");
2110               break;
2111
2112             case V_BIT:
2113               fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
2114               break;
2115
2116             default:
2117               break;
2118             }
2119           fputs (":", of);
2120           if (SPEC_USIGN (type))
2121             fputs ("U", of);
2122           else
2123             fputs ("S", of);
2124         }
2125       type = type->next;
2126     }
2127 }
2128 /*-----------------------------------------------------------------*/
2129 /* cdbSymbol - prints a symbol & its type information for debugger */
2130 /*-----------------------------------------------------------------*/
2131 void 
2132 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2133 {
2134   memmap *map;
2135
2136   if (!sym)
2137     return;
2138   if (!of)
2139     of = stdout;
2140
2141   if (isFunc)
2142     fprintf (of, "F:");
2143   else
2144     fprintf (of, "S:");         /* symbol record */
2145   /* if this is not a structure symbol then
2146      we need to figure out the scope information */
2147   if (!isStructSym)
2148     {
2149       if (!sym->level)
2150         {
2151           /* global */
2152           if (IS_STATIC (sym->etype))
2153             fprintf (of, "F%s$", moduleName);   /* scope is file */
2154           else
2155             fprintf (of, "G$"); /* scope is global */
2156         }
2157       else
2158         /* symbol is local */
2159         fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2160     }
2161   else
2162     fprintf (of, "S$");         /* scope is structure */
2163
2164   /* print the name, & mangled name */
2165   fprintf (of, "%s$%d$%d(", sym->name,
2166            sym->level, sym->block);
2167
2168   cdbTypeInfo (sym->type, of);
2169   fprintf (of, "),");
2170
2171   /* print the address space */
2172   map = SPEC_OCLS (sym->etype);
2173   fprintf (of, "%c,%d,%d",
2174            (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2175
2176   /* if assigned to registers then output register names */
2177   /* if this is a function then print
2178      if is it an interrupt routine & interrupt number
2179      and the register bank it is using */
2180   if (isFunc)
2181     fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
2182              FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
2183   /* alternate location to find this symbol @ : eg registers
2184      or spillication */
2185
2186   if (!isStructSym)
2187     fprintf (of, "\n");
2188 }
2189
2190 /*-----------------------------------------------------------------*/
2191 /* cdbStruct - print a structure for debugger                      */
2192 /*-----------------------------------------------------------------*/
2193 void 
2194 cdbStruct (structdef * sdef, int block, FILE * of,
2195            int inStruct, char *tag)
2196 {
2197   symbol *sym;
2198
2199   fprintf (of, "T:");
2200   /* if block # then must have function scope */
2201   fprintf (of, "F%s$", moduleName);
2202   fprintf (of, "%s[", (tag ? tag : sdef->tag));
2203   for (sym = sdef->fields; sym; sym = sym->next)
2204     {
2205       fprintf (of, "({%d}", sym->offset);
2206       cdbSymbol (sym, of, TRUE, FALSE);
2207       fprintf (of, ")");
2208     }
2209   fprintf (of, "]");
2210   if (!inStruct)
2211     fprintf (of, "\n");
2212 }
2213
2214 /*------------------------------------------------------------------*/
2215 /* cdbStructBlock - calls struct printing for a blcks               */
2216 /*------------------------------------------------------------------*/
2217 void 
2218 cdbStructBlock (int block, FILE * of)
2219 {
2220   int i;
2221   bucket **table = StructTab;
2222   bucket *chain;
2223   wassert (of);
2224
2225   /* go thru the entire  table  */
2226   for (i = 0; i < 256; i++)
2227     {
2228       for (chain = table[i]; chain; chain = chain->next)
2229         {
2230           if (chain->block >= block)
2231             {
2232               cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2233             }
2234         }
2235     }
2236 }
2237
2238 /*-----------------------------------------------------------------*/
2239 /* powof2 - returns power of two for the number if number is pow 2 */
2240 /*-----------------------------------------------------------------*/
2241 int 
2242 powof2 (unsigned long num)
2243 {
2244   int nshifts = 0;
2245   int n1s = 0;
2246
2247   while (num)
2248     {
2249       if (num & 1)
2250         n1s++;
2251       num >>= 1;
2252       nshifts++;
2253     }
2254
2255   if (n1s > 1 || nshifts == 0)
2256     return 0;
2257   return nshifts - 1;
2258 }
2259
2260 symbol *__fsadd;
2261 symbol *__fssub;
2262 symbol *__fsmul;
2263 symbol *__fsdiv;
2264 symbol *__fseq;
2265 symbol *__fsneq;
2266 symbol *__fslt;
2267 symbol *__fslteq;
2268 symbol *__fsgt;
2269 symbol *__fsgteq;
2270
2271 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2272 symbol *__muldiv[3][3][2];
2273 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2274 sym_link *__multypes[3][2];
2275 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2276 symbol *__conv[2][3][2];
2277 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2278 symbol *__rlrr[2][3][2];
2279
2280 sym_link *floatType;
2281
2282 static char *
2283 _mangleFunctionName(char *in)
2284 {
2285   if (port->getMangledFunctionName) 
2286     {
2287       return port->getMangledFunctionName(in);
2288     }
2289   else
2290     {
2291       return in;
2292     }
2293 }
2294
2295 /*-----------------------------------------------------------------*/
2296 /* initCSupport - create functions for C support routines          */
2297 /*-----------------------------------------------------------------*/
2298 void 
2299 initCSupport ()
2300 {
2301   const char *smuldivmod[] =
2302   {
2303     "mul", "div", "mod"
2304   };
2305   const char *sbwd[] =
2306   {
2307     "char", "int", "long"
2308   };
2309   const char *ssu[] =
2310   {
2311     "s", "u"
2312   };
2313   const char *srlrr[] =
2314   {
2315     "rl", "rr"
2316   };
2317
2318   int bwd, su, muldivmod, tofrom, rlrr;
2319
2320   if (getenv("SDCC_NO_C_SUPPORT")) {
2321     /* for debugging only */
2322     return;
2323   }
2324
2325   floatType = newFloatLink ();
2326
2327   for (bwd = 0; bwd < 3; bwd++)
2328     {
2329       sym_link *l;
2330       switch (bwd)
2331         {
2332         case 0:
2333           l = newCharLink ();
2334           break;
2335         case 1:
2336           l = newIntLink ();
2337           break;
2338         case 2:
2339           l = newLongLink ();
2340           break;
2341         default:
2342           assert (0);
2343         }
2344       __multypes[bwd][0] = l;
2345       __multypes[bwd][1] = copyLinkChain (l);
2346       SPEC_USIGN (__multypes[bwd][1]) = 1;
2347     }
2348
2349   __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2350   __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2351   __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2352   __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2353   __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2354   __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2355   __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2356   __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2357   __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2358   __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2359
2360   for (tofrom = 0; tofrom < 2; tofrom++)
2361     {
2362       for (bwd = 0; bwd < 3; bwd++)
2363         {
2364           for (su = 0; su < 2; su++)
2365             {
2366               if (tofrom)
2367                 {
2368                   sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2369                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
2370                 }
2371               else
2372                 {
2373                   sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2374                   __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
2375                 }
2376             }
2377         }
2378     }
2379
2380   for (muldivmod = 0; muldivmod < 3; muldivmod++)
2381     {
2382       for (bwd = 0; bwd < 3; bwd++)
2383         {
2384           for (su = 0; su < 2; su++)
2385             {
2386               sprintf (buffer, "_%s%s%s",
2387                        smuldivmod[muldivmod],
2388                        ssu[su],
2389                        sbwd[bwd]);
2390               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2391               FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
2392             }
2393         }
2394     }
2395
2396   for (rlrr = 0; rlrr < 2; rlrr++)
2397     {
2398       for (bwd = 0; bwd < 3; bwd++)
2399         {
2400           for (su = 0; su < 2; su++)
2401             {
2402               sprintf (buffer, "_%s%s%s",
2403                        srlrr[rlrr],
2404                        ssu[su],
2405                        sbwd[bwd]);
2406               __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
2407               FUNC_NONBANKED (__rlrr[rlrr][bwd][su]->type) = 1;
2408             }
2409         }
2410     }
2411 }