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