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 /* mergeSpec - merges two specifiers and returns the new one */
429 /*------------------------------------------------------------------*/
431 mergeSpec (sym_link * dest, sym_link * src)
433 /* if noun different then src overrides */
434 if (SPEC_NOUN (dest) != SPEC_NOUN (src) && !SPEC_NOUN (dest))
435 SPEC_NOUN (dest) = SPEC_NOUN (src);
437 /* if destination has no storage class */
438 if (!SPEC_SCLS (dest) ||
439 ((SPEC_SCLS(dest) == S_CONSTANT || SPEC_SCLS(dest) == S_REGISTER) &&
441 SPEC_SCLS (dest) = SPEC_SCLS (src);
442 /* special case for const */
443 /* copy all the specifications */
444 SPEC_LONG (dest) |= SPEC_LONG (src);
445 SPEC_SHORT (dest) |= SPEC_SHORT (src);
446 SPEC_USIGN (dest) |= SPEC_USIGN (src);
447 SPEC_STAT (dest) |= SPEC_STAT (src);
448 SPEC_EXTR (dest) |= SPEC_EXTR (src);
449 SPEC_ABSA (dest) |= SPEC_ABSA (src);
450 SPEC_RENT (dest) |= SPEC_RENT (src);
451 SPEC_INTN (dest) |= SPEC_INTN (src);
452 SPEC_BANK (dest) |= SPEC_BANK (src);
453 SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
454 SPEC_CRTCL (dest) |= SPEC_CRTCL (src);
455 SPEC_ADDR (dest) |= SPEC_ADDR (src);
456 SPEC_OCLS (dest) = SPEC_OCLS (src);
457 SPEC_BLEN (dest) |= SPEC_BLEN (src);
458 SPEC_BSTR (dest) |= SPEC_BSTR (src);
459 SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
460 SPEC_NONBANKED (dest) |= SPEC_NONBANKED (src);
461 SPEC_NAKED (dest) |= SPEC_NAKED (src);
463 if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
464 SPEC_STRUCT (dest) = SPEC_STRUCT (src);
469 /*------------------------------------------------------------------*/
470 /* cloneSpec - copies the entire spec and returns a new spec */
471 /*------------------------------------------------------------------*/
473 cloneSpec (sym_link * src)
477 /* go thru chain till we find the specifier */
478 while (src && src->class != SPECIFIER)
482 memcpy (spec, src, sizeof (sym_link));
486 /*------------------------------------------------------------------*/
487 /* genSymName - generates and returns a name used for anonymous vars */
488 /*------------------------------------------------------------------*/
490 genSymName (int level)
492 static int gCount = 0;
493 static char gname[SDCC_NAME_MAX + 1];
495 sprintf (gname, "__%04d%04d", level, gCount++);
499 /*------------------------------------------------------------------*/
500 /* getSpec - returns the specifier part from a declaration chain */
501 /*------------------------------------------------------------------*/
503 getSpec (sym_link * p)
508 while (p && !(IS_SPEC (p)))
514 /*------------------------------------------------------------------*/
515 /* newCharLink() - creates an int type */
516 /*------------------------------------------------------------------*/
523 p->class = SPECIFIER;
524 SPEC_NOUN (p) = V_CHAR;
529 /*------------------------------------------------------------------*/
530 /* newFloatLink - a new Float type */
531 /*------------------------------------------------------------------*/
538 p->class = SPECIFIER;
539 SPEC_NOUN (p) = V_FLOAT;
544 /*------------------------------------------------------------------*/
545 /* newLongLink() - new long type */
546 /*------------------------------------------------------------------*/
553 p->class = SPECIFIER;
554 SPEC_NOUN (p) = V_INT;
560 /*------------------------------------------------------------------*/
561 /* newIntLink() - creates an int type */
562 /*------------------------------------------------------------------*/
569 p->class = SPECIFIER;
570 SPEC_NOUN (p) = V_INT;
575 /*------------------------------------------------------------------*/
576 /* getSize - returns size of a type chain in bits */
577 /*------------------------------------------------------------------*/
579 getSize (sym_link * p)
581 /* if nothing return 0 */
585 { /* if this is the specifier then */
586 switch (SPEC_NOUN (p))
587 { /* depending on the specifier type */
589 return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE));
597 return SPEC_STRUCT (p)->size;
603 return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
609 /* this is a specifier */
610 switch (DCL_TYPE (p))
615 return DCL_ELEM (p) * getSize (p->next);
632 /*------------------------------------------------------------------*/
633 /* bitsForType - returns # of bits required to store this type */
634 /*------------------------------------------------------------------*/
636 bitsForType (sym_link * p)
638 /* if nothing return 0 */
643 { /* if this is the specifier then */
645 switch (SPEC_NOUN (p))
646 { /* depending on the specifier type */
648 return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8));
650 return FLOATSIZE * 8;
656 return SPEC_STRUCT (p)->size * 8;
662 return SPEC_BLEN (p);
668 /* this is a specifier */
669 switch (DCL_TYPE (p))
674 return DCL_ELEM (p) * getSize (p->next) * 8;
678 return (PTRSIZE * 8);
682 return (FPTRSIZE * 8);
684 return (GPTRSIZE * 8);
691 /*------------------------------------------------------------------*/
692 /* copySymbolChain - copies a symbol chain */
693 /*------------------------------------------------------------------*/
695 copySymbolChain (symbol * src)
702 dest = copySymbol (src);
703 dest->next = copySymbolChain (src->next);
707 /*------------------------------------------------------------------*/
708 /* copySymbol - makes a copy of a symbol */
709 /*------------------------------------------------------------------*/
711 copySymbol (symbol * src)
718 dest = newSymbol (src->name, src->level);
719 memcpy (dest, src, sizeof (symbol));
720 dest->level = src->level;
721 dest->block = src->block;
722 dest->ival = copyIlist (src->ival);
723 dest->type = copyLinkChain (src->type);
724 dest->etype = getSpec (dest->type);
726 dest->args = copyValueChain (src->args);
727 dest->key = src->key;
728 dest->calleeSave = src->calleeSave;
729 dest->allocreq = src->allocreq;
733 /*------------------------------------------------------------------*/
734 /* reverseSyms - reverses the links for a symbol chain */
735 /*------------------------------------------------------------------*/
737 reverseSyms (symbol * sym)
739 symbol *prev, *curr, *next;
754 sym->next = (void *) NULL;
758 /*------------------------------------------------------------------*/
759 /* reverseLink - reverses the links for a type chain */
760 /*------------------------------------------------------------------*/
762 reverseLink (sym_link * type)
764 sym_link *prev, *curr, *next;
779 type->next = (void *) NULL;
783 /*------------------------------------------------------------------*/
784 /* addSymChain - adds a symbol chain to the symboltable */
785 /*------------------------------------------------------------------*/
787 addSymChain (symbol * symHead)
789 symbol *sym = symHead;
792 for (; sym != NULL; sym = sym->next)
795 /* if already exists in the symbol table then check if
796 the previous was an extern definition if yes then
797 then check if the type match, if the types match then
798 delete the current entry and add the new entry */
799 if ((csym = findSymWithLevel (SymbolTab, sym)) &&
800 csym->level == sym->level)
803 /* previous definition extern ? */
804 if (IS_EXTERN (csym->etype))
806 /* do types match ? */
807 if (checkType (csym->type, sym->type) != 1)
809 werror (E_DUPLICATE, csym->name);
811 /* delete current entry */
812 deleteSym (SymbolTab, csym, csym->name);
814 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
816 else /* not extern */
817 werror (E_DUPLICATE, sym->name);
821 /* check if previously defined */
822 if (csym && csym->level == sym->level)
824 /* if the previous one was declared as extern */
825 /* then check the type with the current one */
826 if (IS_EXTERN (csym->etype))
828 if (checkType (csym->type, sym->type) <= 0)
829 werror (W_EXTERN_MISMATCH, csym->name);
833 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
838 /*------------------------------------------------------------------*/
839 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
840 /*------------------------------------------------------------------*/
842 funcInChain (sym_link * lnk)
853 /*------------------------------------------------------------------*/
854 /* structElemType - returns the type info of a sturct member */
855 /*------------------------------------------------------------------*/
857 structElemType (sym_link * stype, value * id, value ** argsp)
859 symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
860 sym_link *type, *etype;
861 sym_link *petype = getSpec (stype);
866 /* look for the id */
869 if (strcmp (fields->rname, id->name) == 0)
873 *argsp = fields->args;
875 type = copyLinkChain (fields->type);
876 etype = getSpec (type);
877 SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
878 SPEC_SCLS (etype) : SPEC_SCLS (petype));
881 fields = fields->next;
883 werror (E_NOT_MEMBER, id->name);
888 /*------------------------------------------------------------------*/
889 /* getStructElement - returns element of a tructure definition */
890 /*------------------------------------------------------------------*/
892 getStructElement (structdef * sdef, symbol * sym)
896 for (field = sdef->fields; field; field = field->next)
897 if (strcmp (field->name, sym->name) == 0)
900 werror (E_NOT_MEMBER, sym->name);
905 /*------------------------------------------------------------------*/
906 /* compStructSize - computes the size of a structure */
907 /*------------------------------------------------------------------*/
909 compStructSize (int su, structdef * sdef)
911 int sum = 0, usum = 0;
915 /* for the identifiers */
919 /* create the internal name for this variable */
920 sprintf (loop->rname, "_%s", loop->name);
921 loop->offset = (su == UNION ? sum = 0 : sum);
922 SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
924 /* if this is a bit field */
927 /* change it to a unsigned bit */
928 SPEC_NOUN (loop->etype) = V_BIT;
929 SPEC_USIGN (loop->etype) = 1;
930 /* check if this fit into the remaining */
931 /* bits of this byte else align it to the */
932 /* next byte boundary */
933 if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
934 SPEC_BSTR (loop->etype) = bitOffset;
935 if ((bitOffset += (loop->bitVar % 8)) == 8)
938 else /* does not fit */ {
940 SPEC_BSTR (loop->etype) = bitOffset;
941 sum += (loop->bitVar / 8);
942 bitOffset += (loop->bitVar % 8);
944 /* if this is the last field then pad */
945 if (!loop->next && bitOffset && bitOffset != 8) {
952 sum += getSize (loop->type);
955 /* if function then do the arguments for it */
956 if (funcInChain (loop->type)) {
957 processFuncArgs (loop, 1);
962 /* if this is not a bitfield but the */
963 /* previous one was and did not take */
964 /* the whole byte then pad the rest */
965 if ((loop && !loop->bitVar) && bitOffset) {
970 /* if union then size = sizeof larget field */
972 usum = max (usum, sum);
976 return (su == UNION ? usum : sum);
979 /*------------------------------------------------------------------*/
980 /* checkSClass - check the storage class specification */
981 /*------------------------------------------------------------------*/
983 checkSClass (symbol * sym)
985 /* type is literal can happen foe enums change
987 if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
988 SPEC_SCLS (sym->etype) = S_AUTO;
990 /* if sfr or sbit then must also be */
991 /* volatile the initial value will be xlated */
992 /* to an absolute address */
993 if (SPEC_SCLS (sym->etype) == S_SBIT ||
994 SPEC_SCLS (sym->etype) == S_SFR)
996 SPEC_VOLATILE (sym->etype) = 1;
997 /* if initial value given */
1000 SPEC_ABSA (sym->etype) = 1;
1001 SPEC_ADDR (sym->etype) =
1002 (int) list2int (sym->ival);
1007 /* if absolute address given then it mark it as
1009 if (IS_ABSOLUTE (sym->etype))
1010 SPEC_VOLATILE (sym->etype) = 1;
1012 /* global variables declared const put into code */
1013 if (sym->level == 0 &&
1014 SPEC_SCLS (sym->etype) == S_CONSTANT)
1016 SPEC_SCLS (sym->etype) = S_CODE;
1017 SPEC_CONST (sym->etype) = 1;
1020 /* global variable in code space is a constant */
1021 if (sym->level == 0 &&
1022 SPEC_SCLS (sym->etype) == S_CODE &&
1024 SPEC_CONST (sym->etype) = 1;
1027 /* if bit variable then no storage class can be */
1028 /* specified since bit is already a storage */
1029 if (IS_BITVAR (sym->etype) &&
1030 (SPEC_SCLS (sym->etype) != S_FIXED &&
1031 SPEC_SCLS (sym->etype) != S_SBIT &&
1032 SPEC_SCLS (sym->etype) != S_BIT)
1035 werror (E_BITVAR_STORAGE, sym->name);
1036 SPEC_SCLS (sym->etype) = S_FIXED;
1039 /* extern variables cannot be initialized */
1040 if (IS_EXTERN (sym->etype) && sym->ival)
1042 werror (E_EXTERN_INIT, sym->name);
1046 /* if this is an automatic symbol then */
1047 /* storage class will be ignored and */
1048 /* symbol will be allocated on stack/ */
1049 /* data depending on flag */
1051 (options.stackAuto || reentrant) &&
1052 (SPEC_SCLS (sym->etype) != S_AUTO &&
1053 SPEC_SCLS (sym->etype) != S_FIXED &&
1054 SPEC_SCLS (sym->etype) != S_REGISTER &&
1055 SPEC_SCLS (sym->etype) != S_STACK &&
1056 SPEC_SCLS (sym->etype) != S_XSTACK &&
1057 SPEC_SCLS (sym->etype) != S_CONSTANT))
1059 werror (E_AUTO_ASSUMED, sym->name);
1060 SPEC_SCLS (sym->etype) = S_AUTO;
1063 /* automatic symbols cannot be given */
1064 /* an absolute address ignore it */
1066 SPEC_ABSA (sym->etype) &&
1067 (options.stackAuto || reentrant))
1069 werror (E_AUTO_ABSA, sym->name);
1070 SPEC_ABSA (sym->etype) = 0;
1073 /* arrays & pointers cannot be defined for bits */
1074 /* SBITS or SFRs or BIT */
1075 if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1076 (SPEC_NOUN (sym->etype) == V_BIT ||
1077 SPEC_NOUN (sym->etype) == V_SBIT ||
1078 SPEC_SCLS (sym->etype) == S_SFR))
1079 werror (E_BIT_ARRAY, sym->name);
1081 /* if this is a bit|sbit then set length & start */
1082 if (SPEC_NOUN (sym->etype) == V_BIT ||
1083 SPEC_NOUN (sym->etype) == V_SBIT)
1085 SPEC_BLEN (sym->etype) = 1;
1086 SPEC_BSTR (sym->etype) = 0;
1089 /* variables declared in CODE space must have */
1090 /* initializers if not an extern */
1091 if (SPEC_SCLS (sym->etype) == S_CODE &&
1092 sym->ival == NULL &&
1094 port->mem.code_ro &&
1095 !IS_EXTERN (sym->etype) &&
1096 !funcInChain (sym->type))
1097 werror (E_CODE_NO_INIT, sym->name);
1099 /* if parameter or local variable then change */
1100 /* the storage class to reflect where the var will go */
1101 if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED &&
1102 !IS_STATIC(sym->etype))
1104 if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
1106 SPEC_SCLS (sym->etype) = (options.useXstack ?
1107 S_XSTACK : S_STACK);
1111 /* hack-o-matic! I see no reason why the useXstack option should ever
1112 * control this allcoation, but the code was originally that way, and
1113 * changing it for non-390 ports breaks the compiler badly.
1115 bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1116 SPEC_SCLS (sym->etype) = (useXdata ?
1122 /*------------------------------------------------------------------*/
1123 /* changePointer - change pointer to functions */
1124 /*------------------------------------------------------------------*/
1126 changePointer (symbol * sym)
1130 /* go thru the chain of declarations */
1131 /* if we find a pointer to a function */
1132 /* unconditionally change it to a ptr */
1134 for (p = sym->type; p; p = p->next)
1136 if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1137 DCL_TYPE (p) = GPOINTER;
1138 if (IS_PTR (p) && IS_FUNC (p->next))
1139 DCL_TYPE (p) = CPOINTER;
1143 /*------------------------------------------------------------------*/
1144 /* checkDecl - does semantic validation of a declaration */
1145 /*------------------------------------------------------------------*/
1147 checkDecl (symbol * sym)
1150 checkSClass (sym); /* check the storage class */
1151 changePointer (sym); /* change pointers if required */
1153 /* if this is an array without any dimension
1154 then update the dimension from the initial value */
1155 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1156 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1161 /*------------------------------------------------------------------*/
1162 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1163 /*------------------------------------------------------------------*/
1165 copyLinkChain (sym_link * p)
1167 sym_link *head, *curr, *loop;
1170 head = loop = (curr ? newLink () : (void *) NULL);
1173 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
1174 loop->next = (curr->next ? newLink () : (void *) NULL);
1183 /*------------------------------------------------------------------*/
1184 /* cleanUpBlock - cleansup the symbol table specified for all the */
1185 /* symbols in the given block */
1186 /*------------------------------------------------------------------*/
1188 cleanUpBlock (bucket ** table, int block)
1193 /* go thru the entire table */
1194 for (i = 0; i < 256; i++)
1196 for (chain = table[i]; chain; chain = chain->next)
1198 if (chain->block >= block)
1200 deleteSym (table, chain->sym, chain->name);
1206 /*------------------------------------------------------------------*/
1207 /* cleanUpLevel - cleansup the symbol table specified for all the */
1208 /* symbols in the given level */
1209 /*------------------------------------------------------------------*/
1211 cleanUpLevel (bucket ** table, int level)
1216 /* go thru the entire table */
1217 for (i = 0; i < 256; i++)
1219 for (chain = table[i]; chain; chain = chain->next)
1221 if (chain->level >= level)
1223 deleteSym (table, chain->sym, chain->name);
1229 /*------------------------------------------------------------------*/
1230 /* computeType - computes the resultant type from two types */
1231 /*------------------------------------------------------------------*/
1233 computeType (sym_link * type1, sym_link * type2)
1237 sym_link *etype1 = getSpec (type1);
1238 sym_link *etype2 = getSpec (type2);
1240 /* if one of them is a float then result is a float */
1241 /* here we assume that the types passed are okay */
1242 /* and can be cast to one another */
1243 /* which ever is greater in size */
1244 if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1245 rType = newFloatLink ();
1247 /* if only one of them is a bit variable
1248 then the other one prevails */
1249 if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1250 rType = copyLinkChain (type2);
1251 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1252 rType = copyLinkChain (type1);
1254 /* if one of them is a pointer then that
1257 rType = copyLinkChain (type1);
1258 else if (IS_PTR (type2))
1259 rType = copyLinkChain (type2);
1260 else if (getSize (type1) > getSize (type2))
1261 rType = copyLinkChain (type1);
1263 rType = copyLinkChain (type2);
1265 reType = getSpec (rType);
1267 /* if either of them unsigned then make this unsigned */
1268 if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
1269 SPEC_USIGN (reType) = 1;
1271 /* if result is a literal then make not so */
1272 if (IS_LITERAL (reType))
1273 SPEC_SCLS (reType) = S_REGISTER;
1278 /*------------------------------------------------------------------*/
1279 /* checkType - will do type check return 1 if match */
1280 /*------------------------------------------------------------------*/
1282 checkType (sym_link * dest, sym_link * src)
1293 /* if dest is a declarator then */
1298 if (DCL_TYPE (src) == DCL_TYPE (dest))
1299 return checkType (dest->next, src->next);
1300 else if (IS_PTR (src) && IS_PTR (dest))
1302 else if (IS_PTR (dest) && IS_ARRAY (src))
1304 else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1305 return -1 * checkType (dest->next, src);
1309 else if (IS_PTR (dest) && IS_INTEGRAL (src))
1315 /* if one is a specifier and the other is not */
1316 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1317 (IS_SPEC (dest) && !IS_SPEC (src)))
1320 /* if one of them is a void then ok */
1321 if (SPEC_NOUN (dest) == V_VOID &&
1322 SPEC_NOUN (src) != V_VOID)
1325 if (SPEC_NOUN (dest) != V_VOID &&
1326 SPEC_NOUN (src) == V_VOID)
1329 /* char === to short */
1330 if (SPEC_NOUN (dest) == V_CHAR &&
1331 SPEC_NOUN (src) == V_INT &&
1333 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1335 if (SPEC_NOUN (src) == V_CHAR &&
1336 SPEC_NOUN (dest) == V_INT &&
1338 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1340 /* if they are both bitfields then if the lengths
1341 and starts don't match */
1342 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1343 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1344 SPEC_BSTR (dest) != SPEC_BSTR (src)))
1347 /* it is a specifier */
1348 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1350 if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1351 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1352 getSize (dest) == getSize (src))
1354 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1359 else if (IS_STRUCT (dest))
1361 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1366 if (SPEC_LONG (dest) != SPEC_LONG (src))
1369 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1372 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1378 /*------------------------------------------------------------------*/
1379 /* inCalleeSaveList - return 1 if found in calle save list */
1380 /*------------------------------------------------------------------*/
1382 inCalleeSaveList (char *s)
1386 for (i = 0; options.calleeSaves[i]; i++)
1387 if (strcmp (options.calleeSaves[i], s) == 0)
1393 /*-----------------------------------------------------------------*/
1394 /* aggregateArgToPointer: change an agggregate type function */
1395 /* argument to a pointer to that type. */
1396 /*-----------------------------------------------------------------*/
1398 aggregateArgToPointer (value * val)
1400 if (IS_AGGREGATE (val->type))
1402 /* if this is a structure */
1403 /* then we need to add a new link */
1404 if (IS_STRUCT (val->type))
1406 /* first lets add DECLARATOR type */
1407 sym_link *p = val->type;
1409 werror (W_STRUCT_AS_ARG, val->name);
1410 val->type = newLink ();
1411 val->type->next = p;
1414 /* change to a pointer depending on the */
1415 /* storage class specified */
1416 switch (SPEC_SCLS (val->etype))
1419 DCL_TYPE (val->type) = IPOINTER;
1422 DCL_TYPE (val->type) = PPOINTER;
1425 if (TARGET_IS_DS390)
1427 /* The AUTO and REGISTER classes should probably
1428 * also become generic pointers, but I haven't yet
1429 * devised a test case for that.
1431 DCL_TYPE (val->type) = GPOINTER;
1438 DCL_TYPE (val->type) = POINTER;
1441 DCL_TYPE (val->type) = CPOINTER;
1444 DCL_TYPE (val->type) = FPOINTER;
1447 DCL_TYPE (val->type) = EEPPOINTER;
1450 DCL_TYPE (val->type) = GPOINTER;
1453 /* is there is a symbol associated then */
1454 /* change the type of the symbol as well */
1457 val->sym->type = copyLinkChain (val->type);
1458 val->sym->etype = getSpec (val->sym->type);
1462 /*------------------------------------------------------------------*/
1463 /* checkFunction - does all kinds of check on a function */
1464 /*------------------------------------------------------------------*/
1466 checkFunction (symbol * sym)
1469 value *exargs, *acargs;
1472 /* if not type then some kind of error */
1476 /* if the function has no type then make it return int */
1477 if (!sym->type->next)
1478 sym->type->next = sym->etype = newIntLink ();
1480 /* function cannot return aggregate */
1481 if (IS_AGGREGATE (sym->type->next))
1483 werror (E_FUNC_AGGR, sym->name);
1487 /* function cannot return bit */
1488 if (IS_BITVAR (sym->type->next))
1490 werror (E_FUNC_BIT, sym->name);
1494 /* check if this function is defined as calleeSaves
1495 then mark it as such */
1496 sym->calleeSave = inCalleeSaveList (sym->name);
1498 /* if interrupt service routine */
1499 /* then it cannot have arguments */
1500 if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
1502 werror (E_INT_ARGS, sym->name);
1506 if (!(csym = findSym (SymbolTab, sym, sym->name)))
1507 return 1; /* not defined nothing more to check */
1509 /* check if body already present */
1510 if (csym && csym->fbody)
1512 werror (E_FUNC_BODY, sym->name);
1516 /* check the return value type */
1517 if (checkType (csym->type, sym->type) <= 0)
1519 werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1520 werror (E_CONTINUE, "previous defintion type ");
1521 printTypeChain (csym->type, stderr);
1522 fprintf (stderr, "\n");
1523 werror (E_CONTINUE, "current definition type ");
1524 printTypeChain (sym->type, stderr);
1525 fprintf (stderr, "\n");
1529 if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
1531 werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1535 if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
1537 werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1541 /* compare expected agrs with actual args */
1542 exargs = csym->args;
1545 /* for all the expected args do */
1548 exargs = exargs->next, acargs = acargs->next, argCnt++)
1551 /* If the actual argument is an array, any prototype
1552 * will have modified it to a pointer. Duplicate that
1555 if (IS_AGGREGATE (acargs->type))
1557 checkValue = copyValue (acargs);
1558 aggregateArgToPointer (checkValue);
1562 checkValue = acargs;
1565 if (checkType (exargs->type, checkValue->type) <= 0)
1567 werror (E_ARG_TYPE, argCnt);
1572 /* if one them ended we have a problem */
1573 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1574 (!exargs && acargs && !IS_VOID (acargs->type)))
1575 werror (E_ARG_COUNT);
1577 /* replace with this defition */
1578 sym->cdef = csym->cdef;
1579 deleteSym (SymbolTab, csym, csym->name);
1580 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
1581 if (IS_EXTERN (csym->etype) && !
1582 IS_EXTERN (sym->etype))
1584 addSet (&publics, sym);
1589 /*-----------------------------------------------------------------*/
1590 /* processFuncArgs - does some processing with function args */
1591 /*-----------------------------------------------------------------*/
1593 processFuncArgs (symbol * func, int ignoreName)
1598 /* if this function has variable argument list */
1599 /* then make the function a reentrant one */
1601 SPEC_RENT (func->etype) = 1;
1603 /* check if this function is defined as calleeSaves
1604 then mark it as such */
1605 func->calleeSave = inCalleeSaveList (func->name);
1607 val = func->args; /* loop thru all the arguments */
1609 /* if it is void then remove parameters */
1610 if (val && IS_VOID (val->type))
1616 /* reset regparm for the port */
1617 (*port->reset_regparms) ();
1618 /* if any of the arguments is an aggregate */
1619 /* change it to pointer to the same type */
1622 /* mark it as a register parameter if
1623 the function does not have VA_ARG
1624 and as port dictates */
1625 if (!func->hasVargs &&
1626 (*port->reg_parm) (val->type))
1628 SPEC_REGPARM (val->etype) = 1;
1631 if (IS_AGGREGATE (val->type))
1633 aggregateArgToPointer (val);
1639 /* if this is an internal generated function call */
1641 /* ignore --stack-auto for this one, we don't know how it is compiled */
1642 /* simply trust on --int-long-reent or --float-reent */
1643 if (IS_RENT(func->etype)) {
1647 /* if this function is reentrant or */
1648 /* automatics r 2b stacked then nothing */
1649 if (IS_RENT (func->etype) || options.stackAuto)
1658 /* if a symbolname is not given */
1659 /* synthesize a variable name */
1663 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1664 val->sym = newSymbol (val->name, 1);
1665 SPEC_OCLS (val->etype) = port->mem.default_local_map;
1666 val->sym->type = copyLinkChain (val->type);
1667 val->sym->etype = getSpec (val->sym->type);
1668 val->sym->_isparm = 1;
1669 strcpy (val->sym->rname, val->name);
1670 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1671 SPEC_STAT (func->etype);
1672 addSymChain (val->sym);
1675 else /* symbol name given create synth name */
1678 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1679 strcpy (val->sym->rname, val->name);
1680 val->sym->_isparm = 1;
1681 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1682 (options.model != MODEL_SMALL ? xdata : data);
1683 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1684 SPEC_STAT (func->etype);
1690 /*-----------------------------------------------------------------*/
1691 /* isSymbolEqual - compares two symbols return 1 if they match */
1692 /*-----------------------------------------------------------------*/
1694 isSymbolEqual (symbol * dest, symbol * src)
1696 /* if pointers match then equal */
1700 /* if one of them is null then don't match */
1704 /* if both of them have rname match on rname */
1705 if (dest->rname[0] && src->rname[0])
1706 return (!strcmp (dest->rname, src->rname));
1708 /* otherwise match on name */
1709 return (!strcmp (dest->name, src->name));
1712 void PT(sym_link *type)
1714 printTypeChain(type,0);
1716 /*-----------------------------------------------------------------*/
1717 /* printTypeChain - prints the type chain in human readable form */
1718 /*-----------------------------------------------------------------*/
1720 printTypeChain (sym_link * type, FILE * of)
1734 if (DCL_PTR_VOLATILE(type)) {
1735 fprintf (of, "volatile ");
1737 switch (DCL_TYPE (type))
1740 fprintf (of, "function ");
1743 fprintf (of, "_generic * ");
1744 if (DCL_PTR_CONST (type))
1745 fprintf (of, "const ");
1748 fprintf (of, "_code * ");
1749 if (DCL_PTR_CONST (type))
1750 fprintf (of, "const ");
1753 fprintf (of, "_far * ");
1754 if (DCL_PTR_CONST (type))
1755 fprintf (of, "const ");
1758 fprintf (of, "_eeprom * ");
1759 if (DCL_PTR_CONST (type))
1760 fprintf (of, "const ");
1764 fprintf (of, "_near * ");
1765 if (DCL_PTR_CONST (type))
1766 fprintf (of, "const ");
1769 fprintf (of, "_idata *");
1770 if (DCL_PTR_CONST (type))
1771 fprintf (of, "const ");
1774 fprintf (of, "_pdata *");
1775 if (DCL_PTR_CONST (type))
1776 fprintf (of, "const ");
1779 fprintf (of, " _unkown *");
1780 if (DCL_PTR_CONST (type))
1781 fprintf (of, "const ");
1784 fprintf (of, "array of ");
1790 if (SPEC_VOLATILE (type))
1791 fprintf (of, "volatile ");
1792 if (SPEC_USIGN (type))
1793 fprintf (of, "unsigned ");
1794 if (SPEC_CONST (type))
1795 fprintf (of, "const ");
1797 switch (SPEC_NOUN (type))
1801 fprintf (of, "long ");
1802 else if (IS_SHORT (type))
1803 fprintf (of, "short ");
1805 fprintf (of, "int ");
1809 fprintf (of, "char ");
1813 fprintf (of, "void ");
1817 fprintf (of, "float ");
1821 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1825 fprintf (of, "sbit ");
1829 fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1842 /*-----------------------------------------------------------------*/
1843 /* cdbTypeInfo - print the type information for debugger */
1844 /*-----------------------------------------------------------------*/
1846 cdbTypeInfo (sym_link * type, FILE * of)
1848 fprintf (of, "{%d}", getSize (type));
1853 switch (DCL_TYPE (type))
1856 fprintf (of, "DF,");
1859 fprintf (of, "DG,");
1862 fprintf (of, "DC,");
1865 fprintf (of, "DX,");
1868 fprintf (of, "DD,");
1871 fprintf (of, "DI,");
1874 fprintf (of, "DP,");
1877 fprintf (of, "DA,");
1880 fprintf (of, "DA%d,", DCL_ELEM (type));
1888 switch (SPEC_NOUN (type))
1893 else if (IS_SHORT (type))
1912 fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
1920 fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
1927 if (SPEC_USIGN (type))
1935 /*-----------------------------------------------------------------*/
1936 /* cdbSymbol - prints a symbol & its type information for debugger */
1937 /*-----------------------------------------------------------------*/
1939 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
1951 fprintf (of, "S:"); /* symbol record */
1952 /* if this is not a structure symbol then
1953 we need to figure out the scope information */
1959 if (IS_STATIC (sym->etype))
1960 fprintf (of, "F%s$", moduleName); /* scope is file */
1962 fprintf (of, "G$"); /* scope is global */
1965 /* symbol is local */
1966 fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
1969 fprintf (of, "S$"); /* scope is structure */
1971 /* print the name, & mangled name */
1972 fprintf (of, "%s$%d$%d(", sym->name,
1973 sym->level, sym->block);
1975 cdbTypeInfo (sym->type, of);
1978 /* print the address space */
1979 map = SPEC_OCLS (sym->etype);
1980 fprintf (of, "%c,%d,%d",
1981 (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
1983 /* if assigned to registers then output register names */
1984 /* if this is a function then print
1985 if is it an interrupt routine & interrupt number
1986 and the register bank it is using */
1988 fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
1989 SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
1990 /* alternate location to find this symbol @ : eg registers
1997 /*-----------------------------------------------------------------*/
1998 /* cdbStruct - print a structure for debugger */
1999 /*-----------------------------------------------------------------*/
2001 cdbStruct (structdef * sdef, int block, FILE * of,
2002 int inStruct, char *tag)
2007 /* if block # then must have function scope */
2008 fprintf (of, "F%s$", moduleName);
2009 fprintf (of, "%s[", (tag ? tag : sdef->tag));
2010 for (sym = sdef->fields; sym; sym = sym->next)
2012 fprintf (of, "({%d}", sym->offset);
2013 cdbSymbol (sym, of, TRUE, FALSE);
2021 /*------------------------------------------------------------------*/
2022 /* cdbStructBlock - calls struct printing for a blcks */
2023 /*------------------------------------------------------------------*/
2025 cdbStructBlock (int block, FILE * of)
2028 bucket **table = StructTab;
2032 /* go thru the entire table */
2033 for (i = 0; i < 256; i++)
2035 for (chain = table[i]; chain; chain = chain->next)
2037 if (chain->block >= block)
2039 cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2045 /*-----------------------------------------------------------------*/
2046 /* powof2 - returns power of two for the number if number is pow 2 */
2047 /*-----------------------------------------------------------------*/
2049 powof2 (unsigned long num)
2062 if (n1s > 1 || nshifts == 0)
2078 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2079 symbol *__muldiv[3][3][2];
2080 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2081 sym_link *__multypes[3][2];
2082 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2083 symbol *__conv[2][3][2];
2085 sym_link *floatType;
2088 _makeRegParam (symbol * sym)
2092 val = sym->args; /* loop thru all the arguments */
2094 /* reset regparm for the port */
2095 (*port->reset_regparms) ();
2098 SPEC_REGPARM (val->etype) = 1;
2103 /*-----------------------------------------------------------------*/
2104 /* initCSupport - create functions for C support routines */
2105 /*-----------------------------------------------------------------*/
2109 const char *smuldivmod[] =
2113 const char *sbwd[] =
2115 "char", "int", "long"
2122 int bwd, su, muldivmod, tofrom;
2124 floatType = newFloatLink ();
2126 for (bwd = 0; bwd < 3; bwd++)
2143 __multypes[bwd][0] = l;
2144 __multypes[bwd][1] = copyLinkChain (l);
2145 SPEC_USIGN (__multypes[bwd][1]) = 1;
2148 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2149 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2150 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2151 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2152 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2153 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2154 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2155 __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2156 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2157 __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2159 for (tofrom = 0; tofrom < 2; tofrom++)
2161 for (bwd = 0; bwd < 3; bwd++)
2163 for (su = 0; su < 2; su++)
2167 sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2168 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2172 sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2173 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2179 for (muldivmod = 0; muldivmod < 3; muldivmod++)
2181 for (bwd = 0; bwd < 3; bwd++)
2183 for (su = 0; su < 2; su++)
2185 sprintf (buffer, "_%s%s%s",
2186 smuldivmod[muldivmod],
2189 __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2190 SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2191 if (bwd < port->muldiv.force_reg_param_below)
2192 _makeRegParam (__muldiv[muldivmod][bwd][su]);