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