1 /*-------------------------------------------------------------------------
2 SDCCsymt.c - Code file for Symbols table related structures and MACRO's.
3 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
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
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.
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.
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 -------------------------------------------------------------------------*/
27 bucket *SymbolTab[256]; /* the symbol table */
28 bucket *StructTab[256]; /* the structure table */
29 bucket *TypedefTab[256]; /* the typedef table */
30 bucket *LabelTab[256]; /* the Label table */
31 bucket *enumTab[256]; /* enumerated table */
33 /*------------------------------------------------------------------*/
34 /* initSymt () - initialises symbol table related stuff */
35 /*------------------------------------------------------------------*/
41 for (i = 0; i < 256; i++)
42 SymbolTab[i] = StructTab[i] = (void *) NULL;
46 /*-----------------------------------------------------------------*/
47 /* newBucket - allocates & returns a new bucket */
48 /*-----------------------------------------------------------------*/
54 bp = Safe_calloc (1, sizeof (bucket));
59 /*-----------------------------------------------------------------*/
60 /* hashKey - computes the hashkey given a symbol name */
61 /*-----------------------------------------------------------------*/
63 hashKey (const char *s)
65 unsigned long key = 0;
72 /*-----------------------------------------------------------------*/
73 /* addSym - adds a symbol to the hash Table */
74 /*-----------------------------------------------------------------*/
76 addSym (bucket ** stab,
82 int i; /* index into the hash Table */
83 bucket *bp; /* temp bucket * */
85 /* the symbols are always added at the head of the list */
87 /* get a free entry */
88 bp = Safe_calloc (1, sizeof (bucket));
90 bp->sym = sym; /* update the symbol pointer */
91 bp->level = level; /* update the nest level */
93 strcpy (bp->name, sname); /* copy the name into place */
95 /* if this is the first entry */
98 bp->prev = bp->next = (void *) NULL; /* point to nothing */
101 /* not first entry then add @ head of list */
111 /*-----------------------------------------------------------------*/
112 /* deleteSym - deletes a symbol from the hash Table entry */
113 /*-----------------------------------------------------------------*/
115 deleteSym (bucket ** stab, void *sym, char *sname)
123 /* find the symbol */
126 if (bp->sym == sym) /* found it then break out */
127 break; /* of the loop */
131 if (!bp) /* did not find it */
133 /* if this is the first one in the chain */
137 if (stab[i]) /* if chain ! empty */
138 stab[i]->prev = (void *) NULL;
140 /* middle || end of chain */
143 if (bp->next) /* if not end of chain */
144 bp->next->prev = bp->prev;
146 bp->prev->next = bp->next;
151 /*-----------------------------------------------------------------*/
152 /* findSym - finds a symbol in a table */
153 /*-----------------------------------------------------------------*/
155 findSym (bucket ** stab, void *sym, const char *sname)
159 bp = stab[hashKey (sname)];
162 if (bp->sym == sym || strcmp (bp->name, sname) == 0)
167 return (bp ? bp->sym : (void *) NULL);
170 /*-----------------------------------------------------------------*/
171 /* findSymWithLevel - finds a symbol with a name & level */
172 /*-----------------------------------------------------------------*/
174 findSymWithLevel (bucket ** stab, symbol * sym)
178 bp = stab[hashKey (sym->name)];
181 ** do the search from the head of the list since the
182 ** elements are added at the head it is ensured that
183 ** we will find the deeper definitions before we find
184 ** the global ones. we need to check for symbols with
185 ** level <= to the level given, if levels match then block
186 ** numbers need to match as well
191 if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level)
193 /* if this is parameter then nothing else need to be checked */
194 if (((symbol *) (bp->sym))->_isparm)
196 /* if levels match then block numbers hsould also match */
197 if (bp->level && bp->level == sym->level && bp->block == sym->block)
199 /* if levels don't match then we are okay */
200 if (bp->level && bp->level != sym->level && bp->block <= sym->block)
202 /* if this is a global variable then we are ok too */
210 return (void *) NULL;
213 /*-----------------------------------------------------------------*/
214 /* findSymWithBlock - finds a symbol with name in with a block */
215 /*-----------------------------------------------------------------*/
217 findSymWithBlock (bucket ** stab, symbol * sym, int block)
221 bp = stab[hashKey (sym->name)];
224 if (strcmp (bp->name, sym->name) == 0 &&
230 return (bp ? bp->sym : (void *) NULL);
233 /*------------------------------------------------------------------*/
234 /* newSymbol () - returns a new pointer to a symbol */
235 /*------------------------------------------------------------------*/
237 newSymbol (char *name, int scope)
241 sym = Safe_calloc (1, sizeof (symbol));
243 strcpy (sym->name, name); /* copy the name */
244 sym->level = scope; /* set the level */
245 sym->block = currBlockno;
246 sym->lineDef = yylineno; /* set the line number */
250 /*------------------------------------------------------------------*/
251 /* newLink - creates a new link (declarator,specifier) */
252 /*------------------------------------------------------------------*/
258 p = Safe_calloc (1, sizeof (sym_link));
263 /*------------------------------------------------------------------*/
264 /* newStruct - creats a new structdef from the free list */
265 /*------------------------------------------------------------------*/
267 newStruct (char *tag)
271 s = Safe_calloc (1, sizeof (structdef));
273 strcpy (s->tag, tag); /* copy the tag */
277 /*------------------------------------------------------------------*/
278 /* pointerTypes - do the computation for the pointer types */
279 /*------------------------------------------------------------------*/
281 pointerTypes (sym_link * ptr, sym_link * type)
286 /* find the first pointer type */
287 while (ptr && !IS_PTR (ptr))
290 /* could not find it */
291 if (!ptr || IS_SPEC (ptr) ||
292 DCL_TYPE (ptr) != UPOINTER)
295 /* change the pointer type depending on the
296 storage class of the type */
299 DCL_PTR_CONST (ptr) = SPEC_CONST (type);
300 DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type);
301 switch (SPEC_SCLS (type))
304 DCL_TYPE (ptr) = FPOINTER;
307 DCL_TYPE (ptr) = IPOINTER;
310 DCL_TYPE (ptr) = PPOINTER;
313 DCL_TYPE (ptr) = POINTER;
316 DCL_PTR_CONST (ptr) = port->mem.code_ro;
317 DCL_TYPE (ptr) = CPOINTER;
320 DCL_TYPE (ptr) = EEPPOINTER;
323 DCL_TYPE (ptr) = GPOINTER;
326 /* the storage class of type ends here */
329 SPEC_VOLATILE (type) = 0;
332 /* now change all the remaining unknown pointers
333 to generic pointers */
336 if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER)
337 DCL_TYPE (ptr) = GPOINTER;
341 /* same for the type although it is highly unlikely that
342 type will have a pointer */
345 if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER)
346 DCL_TYPE (type) = GPOINTER;
352 /*------------------------------------------------------------------*/
353 /* addDecl - adds a declarator @ the end of a chain */
354 /*------------------------------------------------------------------*/
356 addDecl (symbol * sym, int type, sym_link * p)
362 /* if we are passed a link then set head & tail */
371 head = tail = newLink ();
372 DCL_TYPE (head) = type;
375 /* if this is the first entry */
383 if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
385 sym->etype = mergeSpec (sym->etype, head);
389 if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail)
392 while (t->next != sym->etype)
395 tail->next = sym->etype;
399 sym->etype->next = head;
405 /* if the type is a unknown pointer and has
406 a tspec then take the storage class const & volatile
407 attribute from the tspec & make it those of this
411 DCL_TYPE (p) == UPOINTER &&
414 if (!IS_SPEC (sym->etype))
416 sym->etype = sym->etype->next = newLink ();
417 sym->etype->class = SPECIFIER;
419 SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
420 SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p));
421 SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
422 DCL_TSPEC (p) = NULL;
427 /*------------------------------------------------------------------
428 checkTypeSanity: prevent the user from doing e.g.:
430 ------------------------------------------------------------------*/
431 void checkTypeSanity(sym_link *dest) {
433 switch (SPEC_NOUN(dest))
435 case V_CHAR: noun="char"; break;
436 case V_INT: noun="int"; break;
437 case V_FLOAT: noun="float"; break;
438 case V_DOUBLE: noun="double"; break;
439 case V_VOID: noun="void"; break;
440 default: noun="unknown type"; break;
443 if ((SPEC_NOUN(dest)==V_CHAR ||
444 SPEC_NOUN(dest)==V_FLOAT ||
445 SPEC_NOUN(dest)==V_DOUBLE ||
446 SPEC_NOUN(dest)==V_VOID) &&
447 (SPEC_SHORT(dest) || SPEC_LONG(dest))) {
448 // long or short for char float double or void
449 werror (E_LONG_OR_SHORT_INVALID, noun, yylval.yychar);
451 if ((SPEC_NOUN(dest)==V_FLOAT ||
452 SPEC_NOUN(dest)==V_DOUBLE ||
453 SPEC_NOUN(dest)==V_VOID) &&
454 (SPEC_SIGNED(dest) || SPEC_USIGN(dest))) {
455 // signed or unsigned for float double or void
456 werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, yylval.yychar);
458 if (SPEC_SIGNED(dest) && SPEC_USIGN(dest)) {
459 // signed AND unsigned
460 werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, yylval.yychar);
462 if (SPEC_SHORT(dest) && SPEC_LONG(dest)) {
464 werror (E_LONG_AND_SHORT_INVALID, noun, yylval.yychar);
468 /*------------------------------------------------------------------*/
469 /* mergeSpec - merges two specifiers and returns the new one */
470 /*------------------------------------------------------------------*/
472 mergeSpec (sym_link * dest, sym_link * src)
475 /* we shouldn't redeclare the type */
476 if (SPEC_NOUN (dest) && SPEC_NOUN (src)) {
477 werror(E_TWO_OR_MORE_DATA_TYPES, yylval.yychar);
480 /* if noun different then src overrides */
481 if (SPEC_NOUN (dest) != SPEC_NOUN (src) && !SPEC_NOUN (dest))
482 SPEC_NOUN (dest) = SPEC_NOUN (src);
484 /* if destination has no storage class */
485 if (!SPEC_SCLS (dest) ||
486 ((SPEC_SCLS(dest) == S_CONSTANT || SPEC_SCLS(dest) == S_REGISTER) &&
488 SPEC_SCLS (dest) = SPEC_SCLS (src);
489 /* special case for const */
490 /* copy all the specifications */
491 SPEC_LONG (dest) |= SPEC_LONG (src);
492 SPEC_SHORT (dest) |= SPEC_SHORT (src);
493 SPEC_USIGN (dest) |= SPEC_USIGN (src);
494 SPEC_SIGNED (dest) |= SPEC_SIGNED (src);
495 SPEC_STAT (dest) |= SPEC_STAT (src);
496 SPEC_EXTR (dest) |= SPEC_EXTR (src);
497 SPEC_ABSA (dest) |= SPEC_ABSA (src);
498 SPEC_RENT (dest) |= SPEC_RENT (src);
499 SPEC_INTN (dest) |= SPEC_INTN (src);
500 SPEC_BANK (dest) |= SPEC_BANK (src);
501 SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
502 SPEC_CRTCL (dest) |= SPEC_CRTCL (src);
503 SPEC_ADDR (dest) |= SPEC_ADDR (src);
504 SPEC_OCLS (dest) = SPEC_OCLS (src);
505 SPEC_BLEN (dest) |= SPEC_BLEN (src);
506 SPEC_BSTR (dest) |= SPEC_BSTR (src);
507 SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
508 SPEC_NONBANKED (dest) |= SPEC_NONBANKED (src);
509 SPEC_NAKED (dest) |= SPEC_NAKED (src);
511 if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
512 SPEC_STRUCT (dest) = SPEC_STRUCT (src);
514 checkTypeSanity(dest);
519 /*------------------------------------------------------------------*/
520 /* cloneSpec - copies the entire spec and returns a new spec */
521 /*------------------------------------------------------------------*/
523 cloneSpec (sym_link * src)
527 /* go thru chain till we find the specifier */
528 while (src && src->class != SPECIFIER)
532 memcpy (spec, src, sizeof (sym_link));
536 /*------------------------------------------------------------------*/
537 /* genSymName - generates and returns a name used for anonymous vars */
538 /*------------------------------------------------------------------*/
540 genSymName (int level)
542 static int gCount = 0;
543 static char gname[SDCC_NAME_MAX + 1];
545 sprintf (gname, "__%04d%04d", level, gCount++);
549 /*------------------------------------------------------------------*/
550 /* getSpec - returns the specifier part from a declaration chain */
551 /*------------------------------------------------------------------*/
553 getSpec (sym_link * p)
558 while (p && !(IS_SPEC (p)))
564 /*------------------------------------------------------------------*/
565 /* newCharLink() - creates an char type */
566 /*------------------------------------------------------------------*/
573 p->class = SPECIFIER;
574 SPEC_NOUN (p) = V_CHAR;
579 /*------------------------------------------------------------------*/
580 /* newFloatLink - a new Float type */
581 /*------------------------------------------------------------------*/
588 p->class = SPECIFIER;
589 SPEC_NOUN (p) = V_FLOAT;
594 /*------------------------------------------------------------------*/
595 /* newLongLink() - new long type */
596 /*------------------------------------------------------------------*/
603 p->class = SPECIFIER;
604 SPEC_NOUN (p) = V_INT;
610 /*------------------------------------------------------------------*/
611 /* newIntLink() - creates an int type */
612 /*------------------------------------------------------------------*/
619 p->class = SPECIFIER;
620 SPEC_NOUN (p) = V_INT;
625 /*------------------------------------------------------------------*/
626 /* getSize - returns size of a type chain in bits */
627 /*------------------------------------------------------------------*/
629 getSize (sym_link * p)
631 /* if nothing return 0 */
635 { /* if this is the specifier then */
636 switch (SPEC_NOUN (p))
637 { /* depending on the specifier type */
639 return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE));
647 return SPEC_STRUCT (p)->size;
653 return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
659 /* this is a specifier */
660 switch (DCL_TYPE (p))
665 return DCL_ELEM (p) * getSize (p->next);
682 /*------------------------------------------------------------------*/
683 /* bitsForType - returns # of bits required to store this type */
684 /*------------------------------------------------------------------*/
686 bitsForType (sym_link * p)
688 /* if nothing return 0 */
693 { /* if this is the specifier then */
695 switch (SPEC_NOUN (p))
696 { /* depending on the specifier type */
698 return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8));
700 return FLOATSIZE * 8;
706 return SPEC_STRUCT (p)->size * 8;
712 return SPEC_BLEN (p);
718 /* this is a specifier */
719 switch (DCL_TYPE (p))
724 return DCL_ELEM (p) * getSize (p->next) * 8;
728 return (PTRSIZE * 8);
732 return (FPTRSIZE * 8);
734 return (GPTRSIZE * 8);
741 /*------------------------------------------------------------------*/
742 /* copySymbolChain - copies a symbol chain */
743 /*------------------------------------------------------------------*/
745 copySymbolChain (symbol * src)
752 dest = copySymbol (src);
753 dest->next = copySymbolChain (src->next);
757 /*------------------------------------------------------------------*/
758 /* copySymbol - makes a copy of a symbol */
759 /*------------------------------------------------------------------*/
761 copySymbol (symbol * src)
768 dest = newSymbol (src->name, src->level);
769 memcpy (dest, src, sizeof (symbol));
770 dest->level = src->level;
771 dest->block = src->block;
772 dest->ival = copyIlist (src->ival);
773 dest->type = copyLinkChain (src->type);
774 dest->etype = getSpec (dest->type);
776 dest->args = copyValueChain (src->args);
777 dest->key = src->key;
778 dest->calleeSave = src->calleeSave;
779 dest->allocreq = src->allocreq;
783 /*------------------------------------------------------------------*/
784 /* reverseSyms - reverses the links for a symbol chain */
785 /*------------------------------------------------------------------*/
787 reverseSyms (symbol * sym)
789 symbol *prev, *curr, *next;
804 sym->next = (void *) NULL;
808 /*------------------------------------------------------------------*/
809 /* reverseLink - reverses the links for a type chain */
810 /*------------------------------------------------------------------*/
812 reverseLink (sym_link * type)
814 sym_link *prev, *curr, *next;
829 type->next = (void *) NULL;
833 /*------------------------------------------------------------------*/
834 /* addSymChain - adds a symbol chain to the symboltable */
835 /*------------------------------------------------------------------*/
837 addSymChain (symbol * symHead)
839 symbol *sym = symHead;
842 for (; sym != NULL; sym = sym->next)
845 /* if already exists in the symbol table then check if
846 the previous was an extern definition if yes then
847 then check if the type match, if the types match then
848 delete the current entry and add the new entry */
849 if ((csym = findSymWithLevel (SymbolTab, sym)) &&
850 csym->level == sym->level)
853 /* previous definition extern ? */
854 if (IS_EXTERN (csym->etype))
856 /* do types match ? */
857 if (checkType (csym->type, sym->type) != 1)
859 werror (E_DUPLICATE, csym->name);
861 /* delete current entry */
862 deleteSym (SymbolTab, csym, csym->name);
864 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
866 else /* not extern */
867 werror (E_DUPLICATE, sym->name);
871 /* check if previously defined */
872 if (csym && csym->level == sym->level)
874 /* if the previous one was declared as extern */
875 /* then check the type with the current one */
876 if (IS_EXTERN (csym->etype))
878 if (checkType (csym->type, sym->type) <= 0)
879 werror (W_EXTERN_MISMATCH, csym->name);
883 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
888 /*------------------------------------------------------------------*/
889 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
890 /*------------------------------------------------------------------*/
892 funcInChain (sym_link * lnk)
903 /*------------------------------------------------------------------*/
904 /* structElemType - returns the type info of a sturct member */
905 /*------------------------------------------------------------------*/
907 structElemType (sym_link * stype, value * id, value ** argsp)
909 symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
910 sym_link *type, *etype;
911 sym_link *petype = getSpec (stype);
916 /* look for the id */
919 if (strcmp (fields->rname, id->name) == 0)
923 *argsp = fields->args;
925 type = copyLinkChain (fields->type);
926 etype = getSpec (type);
927 SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
928 SPEC_SCLS (etype) : SPEC_SCLS (petype));
931 fields = fields->next;
933 werror (E_NOT_MEMBER, id->name);
938 /*------------------------------------------------------------------*/
939 /* getStructElement - returns element of a tructure definition */
940 /*------------------------------------------------------------------*/
942 getStructElement (structdef * sdef, symbol * sym)
946 for (field = sdef->fields; field; field = field->next)
947 if (strcmp (field->name, sym->name) == 0)
950 werror (E_NOT_MEMBER, sym->name);
955 /*------------------------------------------------------------------*/
956 /* compStructSize - computes the size of a structure */
957 /*------------------------------------------------------------------*/
959 compStructSize (int su, structdef * sdef)
961 int sum = 0, usum = 0;
965 /* for the identifiers */
969 /* create the internal name for this variable */
970 sprintf (loop->rname, "_%s", loop->name);
971 loop->offset = (su == UNION ? sum = 0 : sum);
972 SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
974 /* if this is a bit field */
977 /* change it to a unsigned bit */
978 SPEC_NOUN (loop->etype) = V_BIT;
979 SPEC_USIGN (loop->etype) = 1;
980 /* check if this fit into the remaining */
981 /* bits of this byte else align it to the */
982 /* next byte boundary */
983 if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
984 SPEC_BSTR (loop->etype) = bitOffset;
985 if ((bitOffset += (loop->bitVar % 8)) == 8)
988 else /* does not fit */ {
990 SPEC_BSTR (loop->etype) = bitOffset;
991 sum += (loop->bitVar / 8);
992 bitOffset += (loop->bitVar % 8);
994 /* if this is the last field then pad */
995 if (!loop->next && bitOffset && bitOffset != 8) {
1002 sum += getSize (loop->type);
1005 /* if function then do the arguments for it */
1006 if (funcInChain (loop->type)) {
1007 processFuncArgs (loop, 1);
1012 /* if this is not a bitfield but the */
1013 /* previous one was and did not take */
1014 /* the whole byte then pad the rest */
1015 if ((loop && !loop->bitVar) && bitOffset) {
1020 /* if union then size = sizeof larget field */
1022 usum = max (usum, sum);
1026 return (su == UNION ? usum : sum);
1029 /*------------------------------------------------------------------*/
1030 /* checkSClass - check the storage class specification */
1031 /*------------------------------------------------------------------*/
1033 checkSClass (symbol * sym)
1035 /* type is literal can happen foe enums change
1037 if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
1038 SPEC_SCLS (sym->etype) = S_AUTO;
1040 /* if sfr or sbit then must also be */
1041 /* volatile the initial value will be xlated */
1042 /* to an absolute address */
1043 if (SPEC_SCLS (sym->etype) == S_SBIT ||
1044 SPEC_SCLS (sym->etype) == S_SFR)
1046 SPEC_VOLATILE (sym->etype) = 1;
1047 /* if initial value given */
1050 SPEC_ABSA (sym->etype) = 1;
1051 SPEC_ADDR (sym->etype) =
1052 (int) list2int (sym->ival);
1057 /* if absolute address given then it mark it as
1059 if (IS_ABSOLUTE (sym->etype))
1060 SPEC_VOLATILE (sym->etype) = 1;
1062 /* global variables declared const put into code */
1063 if (sym->level == 0 &&
1064 SPEC_SCLS (sym->etype) == S_CONSTANT)
1066 SPEC_SCLS (sym->etype) = S_CODE;
1067 SPEC_CONST (sym->etype) = 1;
1070 /* global variable in code space is a constant */
1071 if (sym->level == 0 &&
1072 SPEC_SCLS (sym->etype) == S_CODE &&
1074 SPEC_CONST (sym->etype) = 1;
1077 /* if bit variable then no storage class can be */
1078 /* specified since bit is already a storage */
1079 if (IS_BITVAR (sym->etype) &&
1080 (SPEC_SCLS (sym->etype) != S_FIXED &&
1081 SPEC_SCLS (sym->etype) != S_SBIT &&
1082 SPEC_SCLS (sym->etype) != S_BIT)
1085 werror (E_BITVAR_STORAGE, sym->name);
1086 SPEC_SCLS (sym->etype) = S_FIXED;
1089 /* extern variables cannot be initialized */
1090 if (IS_EXTERN (sym->etype) && sym->ival)
1092 werror (E_EXTERN_INIT, sym->name);
1096 /* if this is an automatic symbol then */
1097 /* storage class will be ignored and */
1098 /* symbol will be allocated on stack/ */
1099 /* data depending on flag */
1101 (options.stackAuto || reentrant) &&
1102 (SPEC_SCLS (sym->etype) != S_AUTO &&
1103 SPEC_SCLS (sym->etype) != S_FIXED &&
1104 SPEC_SCLS (sym->etype) != S_REGISTER &&
1105 SPEC_SCLS (sym->etype) != S_STACK &&
1106 SPEC_SCLS (sym->etype) != S_XSTACK &&
1107 SPEC_SCLS (sym->etype) != S_CONSTANT))
1109 werror (E_AUTO_ASSUMED, sym->name);
1110 SPEC_SCLS (sym->etype) = S_AUTO;
1113 /* automatic symbols cannot be given */
1114 /* an absolute address ignore it */
1116 SPEC_ABSA (sym->etype) &&
1117 (options.stackAuto || reentrant))
1119 werror (E_AUTO_ABSA, sym->name);
1120 SPEC_ABSA (sym->etype) = 0;
1123 /* arrays & pointers cannot be defined for bits */
1124 /* SBITS or SFRs or BIT */
1125 if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1126 (SPEC_NOUN (sym->etype) == V_BIT ||
1127 SPEC_NOUN (sym->etype) == V_SBIT ||
1128 SPEC_SCLS (sym->etype) == S_SFR))
1129 werror (E_BIT_ARRAY, sym->name);
1131 /* if this is a bit|sbit then set length & start */
1132 if (SPEC_NOUN (sym->etype) == V_BIT ||
1133 SPEC_NOUN (sym->etype) == V_SBIT)
1135 SPEC_BLEN (sym->etype) = 1;
1136 SPEC_BSTR (sym->etype) = 0;
1139 /* variables declared in CODE space must have */
1140 /* initializers if not an extern */
1141 if (SPEC_SCLS (sym->etype) == S_CODE &&
1142 sym->ival == NULL &&
1144 port->mem.code_ro &&
1145 !IS_EXTERN (sym->etype) &&
1146 !funcInChain (sym->type))
1147 werror (E_CODE_NO_INIT, sym->name);
1149 /* if parameter or local variable then change */
1150 /* the storage class to reflect where the var will go */
1151 if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1152 !IS_STATIC(sym->etype))
1154 if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
1156 SPEC_SCLS (sym->etype) = (options.useXstack ?
1157 S_XSTACK : S_STACK);
1161 /* hack-o-matic! I see no reason why the useXstack option should ever
1162 * control this allcoation, but the code was originally that way, and
1163 * changing it for non-390 ports breaks the compiler badly.
1165 bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1166 SPEC_SCLS (sym->etype) = (useXdata ?
1172 /*------------------------------------------------------------------*/
1173 /* changePointer - change pointer to functions */
1174 /*------------------------------------------------------------------*/
1176 changePointer (symbol * sym)
1180 /* go thru the chain of declarations */
1181 /* if we find a pointer to a function */
1182 /* unconditionally change it to a ptr */
1184 for (p = sym->type; p; p = p->next)
1186 if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1187 DCL_TYPE (p) = GPOINTER;
1188 if (IS_PTR (p) && IS_FUNC (p->next))
1189 DCL_TYPE (p) = CPOINTER;
1193 /*------------------------------------------------------------------*/
1194 /* checkDecl - does semantic validation of a declaration */
1195 /*------------------------------------------------------------------*/
1197 checkDecl (symbol * sym)
1200 checkSClass (sym); /* check the storage class */
1201 changePointer (sym); /* change pointers if required */
1203 /* if this is an array without any dimension
1204 then update the dimension from the initial value */
1205 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1206 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1211 /*------------------------------------------------------------------*/
1212 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1213 /*------------------------------------------------------------------*/
1215 copyLinkChain (sym_link * p)
1217 sym_link *head, *curr, *loop;
1220 head = loop = (curr ? newLink () : (void *) NULL);
1223 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
1224 loop->next = (curr->next ? newLink () : (void *) NULL);
1233 /*------------------------------------------------------------------*/
1234 /* cleanUpBlock - cleansup the symbol table specified for all the */
1235 /* symbols in the given block */
1236 /*------------------------------------------------------------------*/
1238 cleanUpBlock (bucket ** table, int block)
1243 /* go thru the entire table */
1244 for (i = 0; i < 256; i++)
1246 for (chain = table[i]; chain; chain = chain->next)
1248 if (chain->block >= block)
1250 deleteSym (table, chain->sym, chain->name);
1256 /*------------------------------------------------------------------*/
1257 /* cleanUpLevel - cleansup the symbol table specified for all the */
1258 /* symbols in the given level */
1259 /*------------------------------------------------------------------*/
1261 cleanUpLevel (bucket ** table, int level)
1266 /* go thru the entire table */
1267 for (i = 0; i < 256; i++)
1269 for (chain = table[i]; chain; chain = chain->next)
1271 if (chain->level >= level)
1273 deleteSym (table, chain->sym, chain->name);
1279 /*------------------------------------------------------------------*/
1280 /* computeType - computes the resultant type from two types */
1281 /*------------------------------------------------------------------*/
1283 computeType (sym_link * type1, sym_link * type2)
1287 sym_link *etype1 = getSpec (type1);
1288 sym_link *etype2 = getSpec (type2);
1290 /* if one of them is a float then result is a float */
1291 /* here we assume that the types passed are okay */
1292 /* and can be cast to one another */
1293 /* which ever is greater in size */
1294 if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1295 rType = newFloatLink ();
1297 /* if only one of them is a bit variable
1298 then the other one prevails */
1299 if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1300 rType = copyLinkChain (type2);
1301 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1302 rType = copyLinkChain (type1);
1304 /* if one of them is a pointer then that
1307 rType = copyLinkChain (type1);
1308 else if (IS_PTR (type2))
1309 rType = copyLinkChain (type2);
1310 else if (getSize (type1) > getSize (type2))
1311 rType = copyLinkChain (type1);
1313 rType = copyLinkChain (type2);
1315 reType = getSpec (rType);
1317 /* if either of them unsigned then make this unsigned */
1318 if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
1319 SPEC_USIGN (reType) = 1;
1321 /* if result is a literal then make not so */
1322 if (IS_LITERAL (reType))
1323 SPEC_SCLS (reType) = S_REGISTER;
1328 /*------------------------------------------------------------------*/
1329 /* checkType - will do type check return 1 if match */
1330 /*------------------------------------------------------------------*/
1332 checkType (sym_link * dest, sym_link * src)
1343 /* if dest is a declarator then */
1348 if (DCL_TYPE (src) == DCL_TYPE (dest))
1349 return checkType (dest->next, src->next);
1350 else if (IS_PTR (src) && IS_PTR (dest))
1352 else if (IS_PTR (dest) && IS_ARRAY (src))
1354 else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1355 return -1 * checkType (dest->next, src);
1359 else if (IS_PTR (dest) && IS_INTEGRAL (src))
1365 /* if one is a specifier and the other is not */
1366 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1367 (IS_SPEC (dest) && !IS_SPEC (src)))
1370 /* if one of them is a void then ok */
1371 if (SPEC_NOUN (dest) == V_VOID &&
1372 SPEC_NOUN (src) != V_VOID)
1375 if (SPEC_NOUN (dest) != V_VOID &&
1376 SPEC_NOUN (src) == V_VOID)
1379 /* char === to short */
1380 if (SPEC_NOUN (dest) == V_CHAR &&
1381 SPEC_NOUN (src) == V_INT &&
1383 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1385 if (SPEC_NOUN (src) == V_CHAR &&
1386 SPEC_NOUN (dest) == V_INT &&
1388 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1390 /* if they are both bitfields then if the lengths
1391 and starts don't match */
1392 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1393 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1394 SPEC_BSTR (dest) != SPEC_BSTR (src)))
1397 /* it is a specifier */
1398 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1400 if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1401 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1402 getSize (dest) == getSize (src))
1404 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1409 else if (IS_STRUCT (dest))
1411 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1416 if (SPEC_LONG (dest) != SPEC_LONG (src))
1419 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1422 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1428 /*------------------------------------------------------------------*/
1429 /* inCalleeSaveList - return 1 if found in calle save list */
1430 /*------------------------------------------------------------------*/
1432 inCalleeSaveList (char *s)
1436 for (i = 0; options.calleeSaves[i]; i++)
1437 if (strcmp (options.calleeSaves[i], s) == 0)
1443 /*-----------------------------------------------------------------*/
1444 /* aggregateArgToPointer: change an agggregate type function */
1445 /* argument to a pointer to that type. */
1446 /*-----------------------------------------------------------------*/
1448 aggregateArgToPointer (value * val)
1450 if (IS_AGGREGATE (val->type))
1452 /* if this is a structure */
1453 /* then we need to add a new link */
1454 if (IS_STRUCT (val->type))
1456 /* first lets add DECLARATOR type */
1457 sym_link *p = val->type;
1459 werror (W_STRUCT_AS_ARG, val->name);
1460 val->type = newLink ();
1461 val->type->next = p;
1464 /* change to a pointer depending on the */
1465 /* storage class specified */
1466 switch (SPEC_SCLS (val->etype))
1469 DCL_TYPE (val->type) = IPOINTER;
1472 DCL_TYPE (val->type) = PPOINTER;
1475 if (TARGET_IS_DS390)
1477 /* The AUTO and REGISTER classes should probably
1478 * also become generic pointers, but I haven't yet
1479 * devised a test case for that.
1481 DCL_TYPE (val->type) = GPOINTER;
1488 DCL_TYPE (val->type) = POINTER;
1491 DCL_TYPE (val->type) = CPOINTER;
1494 DCL_TYPE (val->type) = FPOINTER;
1497 DCL_TYPE (val->type) = EEPPOINTER;
1500 DCL_TYPE (val->type) = GPOINTER;
1503 /* is there is a symbol associated then */
1504 /* change the type of the symbol as well */
1507 val->sym->type = copyLinkChain (val->type);
1508 val->sym->etype = getSpec (val->sym->type);
1512 /*------------------------------------------------------------------*/
1513 /* checkFunction - does all kinds of check on a function */
1514 /*------------------------------------------------------------------*/
1516 checkFunction (symbol * sym)
1519 value *exargs, *acargs;
1522 /* if not type then some kind of error */
1526 /* if the function has no type then make it return int */
1527 if (!sym->type->next)
1528 sym->type->next = sym->etype = newIntLink ();
1530 /* function cannot return aggregate */
1531 if (IS_AGGREGATE (sym->type->next))
1533 werror (E_FUNC_AGGR, sym->name);
1537 /* function cannot return bit */
1538 if (IS_BITVAR (sym->type->next))
1540 werror (E_FUNC_BIT, sym->name);
1544 /* check if this function is defined as calleeSaves
1545 then mark it as such */
1546 sym->calleeSave = inCalleeSaveList (sym->name);
1548 /* if interrupt service routine */
1549 /* then it cannot have arguments */
1550 if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
1552 werror (E_INT_ARGS, sym->name);
1556 if (!(csym = findSym (SymbolTab, sym, sym->name)))
1557 return 1; /* not defined nothing more to check */
1559 /* check if body already present */
1560 if (csym && csym->fbody)
1562 werror (E_FUNC_BODY, sym->name);
1566 /* check the return value type */
1567 if (checkType (csym->type, sym->type) <= 0)
1569 werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1570 werror (E_CONTINUE, "previous defintion type ");
1571 printTypeChain (csym->type, stderr);
1572 fprintf (stderr, "\n");
1573 werror (E_CONTINUE, "current definition type ");
1574 printTypeChain (sym->type, stderr);
1575 fprintf (stderr, "\n");
1579 if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
1581 werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1585 if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
1587 werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1591 /* compare expected agrs with actual args */
1592 exargs = csym->args;
1595 /* for all the expected args do */
1598 exargs = exargs->next, acargs = acargs->next, argCnt++)
1601 /* If the actual argument is an array, any prototype
1602 * will have modified it to a pointer. Duplicate that
1605 if (IS_AGGREGATE (acargs->type))
1607 checkValue = copyValue (acargs);
1608 aggregateArgToPointer (checkValue);
1612 checkValue = acargs;
1615 if (checkType (exargs->type, checkValue->type) <= 0)
1617 werror (E_ARG_TYPE, argCnt);
1622 /* if one them ended we have a problem */
1623 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1624 (!exargs && acargs && !IS_VOID (acargs->type)))
1625 werror (E_ARG_COUNT);
1627 /* replace with this defition */
1628 sym->cdef = csym->cdef;
1629 deleteSym (SymbolTab, csym, csym->name);
1630 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
1631 if (IS_EXTERN (csym->etype) && !
1632 IS_EXTERN (sym->etype))
1634 addSet (&publics, sym);
1639 /*-----------------------------------------------------------------*/
1640 /* processFuncArgs - does some processing with function args */
1641 /*-----------------------------------------------------------------*/
1643 processFuncArgs (symbol * func, int ignoreName)
1648 /* if this function has variable argument list */
1649 /* then make the function a reentrant one */
1651 SPEC_RENT (func->etype) = 1;
1653 /* check if this function is defined as calleeSaves
1654 then mark it as such */
1655 func->calleeSave = inCalleeSaveList (func->name);
1657 val = func->args; /* loop thru all the arguments */
1659 /* if it is void then remove parameters */
1660 if (val && IS_VOID (val->type))
1666 /* reset regparm for the port */
1667 (*port->reset_regparms) ();
1668 /* if any of the arguments is an aggregate */
1669 /* change it to pointer to the same type */
1672 /* mark it as a register parameter if
1673 the function does not have VA_ARG
1674 and as port dictates */
1675 if (!func->hasVargs &&
1676 (*port->reg_parm) (val->type))
1678 SPEC_REGPARM (val->etype) = 1;
1681 if (IS_AGGREGATE (val->type))
1683 aggregateArgToPointer (val);
1689 /* if this is an internal generated function call */
1691 /* ignore --stack-auto for this one, we don't know how it is compiled */
1692 /* simply trust on --int-long-reent or --float-reent */
1693 if (IS_RENT(func->etype)) {
1697 /* if this function is reentrant or */
1698 /* automatics r 2b stacked then nothing */
1699 if (IS_RENT (func->etype) || options.stackAuto)
1708 /* if a symbolname is not given */
1709 /* synthesize a variable name */
1713 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1714 val->sym = newSymbol (val->name, 1);
1715 SPEC_OCLS (val->etype) = port->mem.default_local_map;
1716 val->sym->type = copyLinkChain (val->type);
1717 val->sym->etype = getSpec (val->sym->type);
1718 val->sym->_isparm = 1;
1719 strcpy (val->sym->rname, val->name);
1720 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1721 SPEC_STAT (func->etype);
1722 addSymChain (val->sym);
1725 else /* symbol name given create synth name */
1728 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1729 strcpy (val->sym->rname, val->name);
1730 val->sym->_isparm = 1;
1731 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1732 (options.model != MODEL_SMALL ? xdata : data);
1733 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1734 SPEC_STAT (func->etype);
1740 /*-----------------------------------------------------------------*/
1741 /* isSymbolEqual - compares two symbols return 1 if they match */
1742 /*-----------------------------------------------------------------*/
1744 isSymbolEqual (symbol * dest, symbol * src)
1746 /* if pointers match then equal */
1750 /* if one of them is null then don't match */
1754 /* if both of them have rname match on rname */
1755 if (dest->rname[0] && src->rname[0])
1756 return (!strcmp (dest->rname, src->rname));
1758 /* otherwise match on name */
1759 return (!strcmp (dest->name, src->name));
1762 void PT(sym_link *type)
1764 printTypeChain(type,0);
1766 /*-----------------------------------------------------------------*/
1767 /* printTypeChain - prints the type chain in human readable form */
1768 /*-----------------------------------------------------------------*/
1770 printTypeChain (sym_link * type, FILE * of)
1784 if (DCL_PTR_VOLATILE(type)) {
1785 fprintf (of, "volatile ");
1787 switch (DCL_TYPE (type))
1790 fprintf (of, "function ");
1793 fprintf (of, "_generic * ");
1794 if (DCL_PTR_CONST (type))
1795 fprintf (of, "const ");
1798 fprintf (of, "_code * ");
1799 if (DCL_PTR_CONST (type))
1800 fprintf (of, "const ");
1803 fprintf (of, "_far * ");
1804 if (DCL_PTR_CONST (type))
1805 fprintf (of, "const ");
1808 fprintf (of, "_eeprom * ");
1809 if (DCL_PTR_CONST (type))
1810 fprintf (of, "const ");
1814 fprintf (of, "_near * ");
1815 if (DCL_PTR_CONST (type))
1816 fprintf (of, "const ");
1819 fprintf (of, "_idata *");
1820 if (DCL_PTR_CONST (type))
1821 fprintf (of, "const ");
1824 fprintf (of, "_pdata *");
1825 if (DCL_PTR_CONST (type))
1826 fprintf (of, "const ");
1829 fprintf (of, " _unkown *");
1830 if (DCL_PTR_CONST (type))
1831 fprintf (of, "const ");
1834 fprintf (of, "array of ");
1840 if (SPEC_VOLATILE (type))
1841 fprintf (of, "volatile ");
1842 if (SPEC_USIGN (type))
1843 fprintf (of, "unsigned ");
1844 if (SPEC_CONST (type))
1845 fprintf (of, "const ");
1847 switch (SPEC_NOUN (type))
1851 fprintf (of, "long ");
1852 else if (IS_SHORT (type))
1853 fprintf (of, "short ");
1855 fprintf (of, "int ");
1859 fprintf (of, "char ");
1863 fprintf (of, "void ");
1867 fprintf (of, "float ");
1871 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1875 fprintf (of, "sbit ");
1879 fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1892 /*-----------------------------------------------------------------*/
1893 /* cdbTypeInfo - print the type information for debugger */
1894 /*-----------------------------------------------------------------*/
1896 cdbTypeInfo (sym_link * type, FILE * of)
1898 fprintf (of, "{%d}", getSize (type));
1903 switch (DCL_TYPE (type))
1906 fprintf (of, "DF,");
1909 fprintf (of, "DG,");
1912 fprintf (of, "DC,");
1915 fprintf (of, "DX,");
1918 fprintf (of, "DD,");
1921 fprintf (of, "DI,");
1924 fprintf (of, "DP,");
1927 fprintf (of, "DA,");
1930 fprintf (of, "DA%d,", DCL_ELEM (type));
1938 switch (SPEC_NOUN (type))
1943 else if (IS_SHORT (type))
1962 fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
1970 fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
1977 if (SPEC_USIGN (type))
1985 /*-----------------------------------------------------------------*/
1986 /* cdbSymbol - prints a symbol & its type information for debugger */
1987 /*-----------------------------------------------------------------*/
1989 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
2001 fprintf (of, "S:"); /* symbol record */
2002 /* if this is not a structure symbol then
2003 we need to figure out the scope information */
2009 if (IS_STATIC (sym->etype))
2010 fprintf (of, "F%s$", moduleName); /* scope is file */
2012 fprintf (of, "G$"); /* scope is global */
2015 /* symbol is local */
2016 fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
2019 fprintf (of, "S$"); /* scope is structure */
2021 /* print the name, & mangled name */
2022 fprintf (of, "%s$%d$%d(", sym->name,
2023 sym->level, sym->block);
2025 cdbTypeInfo (sym->type, of);
2028 /* print the address space */
2029 map = SPEC_OCLS (sym->etype);
2030 fprintf (of, "%c,%d,%d",
2031 (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
2033 /* if assigned to registers then output register names */
2034 /* if this is a function then print
2035 if is it an interrupt routine & interrupt number
2036 and the register bank it is using */
2038 fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
2039 SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
2040 /* alternate location to find this symbol @ : eg registers
2047 /*-----------------------------------------------------------------*/
2048 /* cdbStruct - print a structure for debugger */
2049 /*-----------------------------------------------------------------*/
2051 cdbStruct (structdef * sdef, int block, FILE * of,
2052 int inStruct, char *tag)
2057 /* if block # then must have function scope */
2058 fprintf (of, "F%s$", moduleName);
2059 fprintf (of, "%s[", (tag ? tag : sdef->tag));
2060 for (sym = sdef->fields; sym; sym = sym->next)
2062 fprintf (of, "({%d}", sym->offset);
2063 cdbSymbol (sym, of, TRUE, FALSE);
2071 /*------------------------------------------------------------------*/
2072 /* cdbStructBlock - calls struct printing for a blcks */
2073 /*------------------------------------------------------------------*/
2075 cdbStructBlock (int block, FILE * of)
2078 bucket **table = StructTab;
2082 /* go thru the entire table */
2083 for (i = 0; i < 256; i++)
2085 for (chain = table[i]; chain; chain = chain->next)
2087 if (chain->block >= block)
2089 cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2095 /*-----------------------------------------------------------------*/
2096 /* powof2 - returns power of two for the number if number is pow 2 */
2097 /*-----------------------------------------------------------------*/
2099 powof2 (unsigned long num)
2112 if (n1s > 1 || nshifts == 0)
2128 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2129 symbol *__muldiv[3][3][2];
2130 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2131 sym_link *__multypes[3][2];
2132 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2133 symbol *__conv[2][3][2];
2135 sym_link *floatType;
2138 _makeRegParam (symbol * sym)
2142 val = sym->args; /* loop thru all the arguments */
2144 /* reset regparm for the port */
2145 (*port->reset_regparms) ();
2148 SPEC_REGPARM (val->etype) = 1;
2153 /*-----------------------------------------------------------------*/
2154 /* initCSupport - create functions for C support routines */
2155 /*-----------------------------------------------------------------*/
2159 const char *smuldivmod[] =
2163 const char *sbwd[] =
2165 "char", "int", "long"
2172 int bwd, su, muldivmod, tofrom;
2174 floatType = newFloatLink ();
2176 for (bwd = 0; bwd < 3; bwd++)
2193 __multypes[bwd][0] = l;
2194 __multypes[bwd][1] = copyLinkChain (l);
2195 SPEC_USIGN (__multypes[bwd][1]) = 1;
2198 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2199 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2200 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2201 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2202 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2203 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2204 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2205 __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2206 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2207 __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2209 for (tofrom = 0; tofrom < 2; tofrom++)
2211 for (bwd = 0; bwd < 3; bwd++)
2213 for (su = 0; su < 2; su++)
2217 sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2218 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2222 sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2223 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2229 for (muldivmod = 0; muldivmod < 3; muldivmod++)
2231 for (bwd = 0; bwd < 3; bwd++)
2233 for (su = 0; su < 2; su++)
2235 sprintf (buffer, "_%s%s%s",
2236 smuldivmod[muldivmod],
2239 __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2240 SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2241 if (bwd < port->muldiv.force_reg_param_below)
2242 _makeRegParam (__muldiv[muldivmod][bwd][su]);