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