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