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);
462 if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
463 SPEC_STRUCT (dest) = SPEC_STRUCT (src);
468 /*------------------------------------------------------------------*/
469 /* cloneSpec - copies the entire spec and returns a new spec */
470 /*------------------------------------------------------------------*/
472 cloneSpec (sym_link * src)
476 /* go thru chain till we find the specifier */
477 while (src && src->class != SPECIFIER)
481 memcpy (spec, src, sizeof (sym_link));
485 /*------------------------------------------------------------------*/
486 /* genSymName - generates and returns a name used for anonymous vars */
487 /*------------------------------------------------------------------*/
489 genSymName (int level)
491 static int gCount = 0;
492 static char gname[SDCC_NAME_MAX + 1];
494 sprintf (gname, "__%04d%04d", level, gCount++);
498 /*------------------------------------------------------------------*/
499 /* getSpec - returns the specifier part from a declaration chain */
500 /*------------------------------------------------------------------*/
502 getSpec (sym_link * p)
507 while (p && !(IS_SPEC (p)))
513 /*------------------------------------------------------------------*/
514 /* newCharLink() - creates an int type */
515 /*------------------------------------------------------------------*/
522 p->class = SPECIFIER;
523 SPEC_NOUN (p) = V_CHAR;
528 /*------------------------------------------------------------------*/
529 /* newFloatLink - a new Float type */
530 /*------------------------------------------------------------------*/
537 p->class = SPECIFIER;
538 SPEC_NOUN (p) = V_FLOAT;
543 /*------------------------------------------------------------------*/
544 /* newLongLink() - new long type */
545 /*------------------------------------------------------------------*/
552 p->class = SPECIFIER;
553 SPEC_NOUN (p) = V_INT;
559 /*------------------------------------------------------------------*/
560 /* newIntLink() - creates an int type */
561 /*------------------------------------------------------------------*/
568 p->class = SPECIFIER;
569 SPEC_NOUN (p) = V_INT;
574 /*------------------------------------------------------------------*/
575 /* getSize - returns size of a type chain in bits */
576 /*------------------------------------------------------------------*/
578 getSize (sym_link * p)
580 /* if nothing return 0 */
584 { /* if this is the specifier then */
585 switch (SPEC_NOUN (p))
586 { /* depending on the specifier type */
588 return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE));
596 return SPEC_STRUCT (p)->size;
602 return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
608 /* this is a specifier */
609 switch (DCL_TYPE (p))
614 return DCL_ELEM (p) * getSize (p->next);
631 /*------------------------------------------------------------------*/
632 /* bitsForType - returns # of bits required to store this type */
633 /*------------------------------------------------------------------*/
635 bitsForType (sym_link * p)
637 /* if nothing return 0 */
642 { /* if this is the specifier then */
644 switch (SPEC_NOUN (p))
645 { /* depending on the specifier type */
647 return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8));
649 return FLOATSIZE * 8;
655 return SPEC_STRUCT (p)->size * 8;
661 return SPEC_BLEN (p);
667 /* this is a specifier */
668 switch (DCL_TYPE (p))
673 return DCL_ELEM (p) * getSize (p->next) * 8;
677 return (PTRSIZE * 8);
681 return (FPTRSIZE * 8);
683 return (GPTRSIZE * 8);
690 /*------------------------------------------------------------------*/
691 /* copySymbolChain - copies a symbol chain */
692 /*------------------------------------------------------------------*/
694 copySymbolChain (symbol * src)
701 dest = copySymbol (src);
702 dest->next = copySymbolChain (src->next);
706 /*------------------------------------------------------------------*/
707 /* copySymbol - makes a copy of a symbol */
708 /*------------------------------------------------------------------*/
710 copySymbol (symbol * src)
717 dest = newSymbol (src->name, src->level);
718 memcpy (dest, src, sizeof (symbol));
719 dest->level = src->level;
720 dest->block = src->block;
721 dest->ival = copyIlist (src->ival);
722 dest->type = copyLinkChain (src->type);
723 dest->etype = getSpec (dest->type);
725 dest->args = copyValueChain (src->args);
726 dest->key = src->key;
727 dest->calleeSave = src->calleeSave;
728 dest->allocreq = src->allocreq;
732 /*------------------------------------------------------------------*/
733 /* reverseSyms - reverses the links for a symbol chain */
734 /*------------------------------------------------------------------*/
736 reverseSyms (symbol * sym)
738 symbol *prev, *curr, *next;
753 sym->next = (void *) NULL;
757 /*------------------------------------------------------------------*/
758 /* reverseLink - reverses the links for a type chain */
759 /*------------------------------------------------------------------*/
761 reverseLink (sym_link * type)
763 sym_link *prev, *curr, *next;
778 type->next = (void *) NULL;
782 /*------------------------------------------------------------------*/
783 /* addSymChain - adds a symbol chain to the symboltable */
784 /*------------------------------------------------------------------*/
786 addSymChain (symbol * symHead)
788 symbol *sym = symHead;
791 for (; sym != NULL; sym = sym->next)
794 /* if already exists in the symbol table then check if
795 the previous was an extern definition if yes then
796 then check if the type match, if the types match then
797 delete the current entry and add the new entry */
798 if ((csym = findSymWithLevel (SymbolTab, sym)) &&
799 csym->level == sym->level)
802 /* previous definition extern ? */
803 if (IS_EXTERN (csym->etype))
805 /* do types match ? */
806 if (checkType (csym->type, sym->type) != 1)
808 werror (E_DUPLICATE, csym->name);
810 /* delete current entry */
811 deleteSym (SymbolTab, csym, csym->name);
813 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
815 else /* not extern */
816 werror (E_DUPLICATE, sym->name);
820 /* check if previously defined */
821 if (csym && csym->level == sym->level)
823 /* if the previous one was declared as extern */
824 /* then check the type with the current one */
825 if (IS_EXTERN (csym->etype))
827 if (checkType (csym->type, sym->type) <= 0)
828 werror (W_EXTERN_MISMATCH, csym->name);
832 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
837 /*------------------------------------------------------------------*/
838 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
839 /*------------------------------------------------------------------*/
841 funcInChain (sym_link * lnk)
852 /*------------------------------------------------------------------*/
853 /* structElemType - returns the type info of a sturct member */
854 /*------------------------------------------------------------------*/
856 structElemType (sym_link * stype, value * id, value ** argsp)
858 symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
859 sym_link *type, *etype;
860 sym_link *petype = getSpec (stype);
865 /* look for the id */
868 if (strcmp (fields->rname, id->name) == 0)
872 *argsp = fields->args;
874 type = copyLinkChain (fields->type);
875 etype = getSpec (type);
876 SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
877 SPEC_SCLS (etype) : SPEC_SCLS (petype));
880 fields = fields->next;
882 werror (E_NOT_MEMBER, id->name);
887 /*------------------------------------------------------------------*/
888 /* getStructElement - returns element of a tructure definition */
889 /*------------------------------------------------------------------*/
891 getStructElement (structdef * sdef, symbol * sym)
895 for (field = sdef->fields; field; field = field->next)
896 if (strcmp (field->name, sym->name) == 0)
899 werror (E_NOT_MEMBER, sym->name);
904 /*------------------------------------------------------------------*/
905 /* compStructSize - computes the size of a structure */
906 /*------------------------------------------------------------------*/
908 compStructSize (int su, structdef * sdef)
910 int sum = 0, usum = 0;
914 /* for the identifiers */
918 /* create the internal name for this variable */
919 sprintf (loop->rname, "_%s", loop->name);
920 loop->offset = (su == UNION ? sum = 0 : sum);
921 SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
923 /* if this is a bit field */
926 /* change it to a unsigned bit */
927 SPEC_NOUN (loop->etype) = V_BIT;
928 SPEC_USIGN (loop->etype) = 1;
929 /* check if this fit into the remaining */
930 /* bits of this byte else align it to the */
931 /* next byte boundary */
932 if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
933 SPEC_BSTR (loop->etype) = bitOffset;
934 if ((bitOffset += (loop->bitVar % 8)) == 8)
937 else /* does not fit */ {
939 SPEC_BSTR (loop->etype) = bitOffset;
940 sum += (loop->bitVar / 8);
941 bitOffset += (loop->bitVar % 8);
943 /* if this is the last field then pad */
944 if (!loop->next && bitOffset && bitOffset != 8) {
951 sum += getSize (loop->type);
954 /* if function then do the arguments for it */
955 if (funcInChain (loop->type)) {
956 processFuncArgs (loop, 1);
961 /* if this is not a bitfield but the */
962 /* previous one was and did not take */
963 /* the whole byte then pad the rest */
964 if ((loop && !loop->bitVar) && bitOffset) {
969 /* if union then size = sizeof larget field */
971 usum = max (usum, sum);
975 return (su == UNION ? usum : sum);
978 /*------------------------------------------------------------------*/
979 /* checkSClass - check the storage class specification */
980 /*------------------------------------------------------------------*/
982 checkSClass (symbol * sym)
984 /* type is literal can happen foe enums change
986 if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
987 SPEC_SCLS (sym->etype) = S_AUTO;
989 /* if sfr or sbit then must also be */
990 /* volatile the initial value will be xlated */
991 /* to an absolute address */
992 if (SPEC_SCLS (sym->etype) == S_SBIT ||
993 SPEC_SCLS (sym->etype) == S_SFR)
995 SPEC_VOLATILE (sym->etype) = 1;
996 /* if initial value given */
999 SPEC_ABSA (sym->etype) = 1;
1000 SPEC_ADDR (sym->etype) =
1001 (int) list2int (sym->ival);
1006 /* if absolute address given then it mark it as
1008 if (IS_ABSOLUTE (sym->etype))
1009 SPEC_VOLATILE (sym->etype) = 1;
1011 /* global variables declared const put into code */
1012 if (sym->level == 0 &&
1013 SPEC_SCLS (sym->etype) == S_CONSTANT)
1015 SPEC_SCLS (sym->etype) = S_CODE;
1016 SPEC_CONST (sym->etype) = 1;
1019 /* global variable in code space is a constant */
1020 if (sym->level == 0 &&
1021 SPEC_SCLS (sym->etype) == S_CODE &&
1023 SPEC_CONST (sym->etype) = 1;
1026 /* if bit variable then no storage class can be */
1027 /* specified since bit is already a storage */
1028 if (IS_BITVAR (sym->etype) &&
1029 (SPEC_SCLS (sym->etype) != S_FIXED &&
1030 SPEC_SCLS (sym->etype) != S_SBIT &&
1031 SPEC_SCLS (sym->etype) != S_BIT)
1034 werror (E_BITVAR_STORAGE, sym->name);
1035 SPEC_SCLS (sym->etype) = S_FIXED;
1038 /* extern variables cannot be initialized */
1039 if (IS_EXTERN (sym->etype) && sym->ival)
1041 werror (E_EXTERN_INIT, sym->name);
1045 /* if this is an automatic symbol then */
1046 /* storage class will be ignored and */
1047 /* symbol will be allocated on stack/ */
1048 /* data depending on flag */
1050 (options.stackAuto || reentrant) &&
1051 (SPEC_SCLS (sym->etype) != S_AUTO &&
1052 SPEC_SCLS (sym->etype) != S_FIXED &&
1053 SPEC_SCLS (sym->etype) != S_REGISTER &&
1054 SPEC_SCLS (sym->etype) != S_STACK &&
1055 SPEC_SCLS (sym->etype) != S_XSTACK &&
1056 SPEC_SCLS (sym->etype) != S_CONSTANT))
1058 werror (E_AUTO_ASSUMED, sym->name);
1059 SPEC_SCLS (sym->etype) = S_AUTO;
1062 /* automatic symbols cannot be given */
1063 /* an absolute address ignore it */
1065 SPEC_ABSA (sym->etype) &&
1066 (options.stackAuto || reentrant))
1068 werror (E_AUTO_ABSA, sym->name);
1069 SPEC_ABSA (sym->etype) = 0;
1072 /* arrays & pointers cannot be defined for bits */
1073 /* SBITS or SFRs or BIT */
1074 if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1075 (SPEC_NOUN (sym->etype) == V_BIT ||
1076 SPEC_NOUN (sym->etype) == V_SBIT ||
1077 SPEC_SCLS (sym->etype) == S_SFR))
1078 werror (E_BIT_ARRAY, sym->name);
1080 /* if this is a bit|sbit then set length & start */
1081 if (SPEC_NOUN (sym->etype) == V_BIT ||
1082 SPEC_NOUN (sym->etype) == V_SBIT)
1084 SPEC_BLEN (sym->etype) = 1;
1085 SPEC_BSTR (sym->etype) = 0;
1088 /* variables declared in CODE space must have */
1089 /* initializers if not an extern */
1090 if (SPEC_SCLS (sym->etype) == S_CODE &&
1091 sym->ival == NULL &&
1093 port->mem.code_ro &&
1094 !IS_EXTERN (sym->etype) &&
1095 !funcInChain (sym->type))
1096 werror (E_CODE_NO_INIT, sym->name);
1098 /* if parameter or local variable then change */
1099 /* the storage class to reflect where the var will go */
1100 if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED)
1102 if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
1104 SPEC_SCLS (sym->etype) = (options.useXstack ?
1105 S_XSTACK : S_STACK);
1109 /* hack-o-matic! I see no reason why the useXstack option should ever
1110 * control this allcoation, but the code was originally that way, and
1111 * changing it for non-390 ports breaks the compiler badly.
1113 bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1114 SPEC_SCLS (sym->etype) = (useXdata ?
1120 /*------------------------------------------------------------------*/
1121 /* changePointer - change pointer to functions */
1122 /*------------------------------------------------------------------*/
1124 changePointer (symbol * sym)
1128 /* go thru the chain of declarations */
1129 /* if we find a pointer to a function */
1130 /* unconditionally change it to a ptr */
1132 for (p = sym->type; p; p = p->next)
1134 if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1135 DCL_TYPE (p) = GPOINTER;
1136 if (IS_PTR (p) && IS_FUNC (p->next))
1137 DCL_TYPE (p) = CPOINTER;
1141 /*------------------------------------------------------------------*/
1142 /* checkDecl - does semantic validation of a declaration */
1143 /*------------------------------------------------------------------*/
1145 checkDecl (symbol * sym)
1148 checkSClass (sym); /* check the storage class */
1149 changePointer (sym); /* change pointers if required */
1151 /* if this is an array without any dimension
1152 then update the dimension from the initial value */
1153 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1154 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1159 /*------------------------------------------------------------------*/
1160 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1161 /*------------------------------------------------------------------*/
1163 copyLinkChain (sym_link * p)
1165 sym_link *head, *curr, *loop;
1168 head = loop = (curr ? newLink () : (void *) NULL);
1171 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
1172 loop->next = (curr->next ? newLink () : (void *) NULL);
1181 /*------------------------------------------------------------------*/
1182 /* cleanUpBlock - cleansup the symbol table specified for all the */
1183 /* symbols in the given block */
1184 /*------------------------------------------------------------------*/
1186 cleanUpBlock (bucket ** table, int block)
1191 /* go thru the entire table */
1192 for (i = 0; i < 256; i++)
1194 for (chain = table[i]; chain; chain = chain->next)
1196 if (chain->block >= block)
1198 deleteSym (table, chain->sym, chain->name);
1204 /*------------------------------------------------------------------*/
1205 /* cleanUpLevel - cleansup the symbol table specified for all the */
1206 /* symbols in the given level */
1207 /*------------------------------------------------------------------*/
1209 cleanUpLevel (bucket ** table, int level)
1214 /* go thru the entire table */
1215 for (i = 0; i < 256; i++)
1217 for (chain = table[i]; chain; chain = chain->next)
1219 if (chain->level >= level)
1221 deleteSym (table, chain->sym, chain->name);
1227 /*------------------------------------------------------------------*/
1228 /* computeType - computes the resultant type from two types */
1229 /*------------------------------------------------------------------*/
1231 computeType (sym_link * type1, sym_link * type2)
1235 sym_link *etype1 = getSpec (type1);
1236 sym_link *etype2 = getSpec (type2);
1238 /* if one of them is a float then result is a float */
1239 /* here we assume that the types passed are okay */
1240 /* and can be cast to one another */
1241 /* which ever is greater in size */
1242 if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1243 rType = newFloatLink ();
1245 /* if only one of them is a bit variable
1246 then the other one prevails */
1247 if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1248 rType = copyLinkChain (type2);
1249 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1250 rType = copyLinkChain (type1);
1252 /* if one of them is a pointer then that
1255 rType = copyLinkChain (type1);
1256 else if (IS_PTR (type2))
1257 rType = copyLinkChain (type2);
1258 else if (getSize (type1) > getSize (type2))
1259 rType = copyLinkChain (type1);
1261 rType = copyLinkChain (type2);
1263 reType = getSpec (rType);
1265 /* if either of them unsigned then make this unsigned */
1266 if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
1267 SPEC_USIGN (reType) = 1;
1269 /* if result is a literal then make not so */
1270 if (IS_LITERAL (reType))
1271 SPEC_SCLS (reType) = S_REGISTER;
1276 /*------------------------------------------------------------------*/
1277 /* checkType - will do type check return 1 if match */
1278 /*------------------------------------------------------------------*/
1280 checkType (sym_link * dest, sym_link * src)
1291 /* if dest is a declarator then */
1296 if (DCL_TYPE (src) == DCL_TYPE (dest))
1297 return checkType (dest->next, src->next);
1298 else if (IS_PTR (src) && IS_PTR (dest))
1300 else if (IS_PTR (dest) && IS_ARRAY (src))
1302 else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1303 return -1 * checkType (dest->next, src);
1307 else if (IS_PTR (dest) && IS_INTEGRAL (src))
1313 /* if one is a specifier and the other is not */
1314 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1315 (IS_SPEC (dest) && !IS_SPEC (src)))
1318 /* if one of them is a void then ok */
1319 if (SPEC_NOUN (dest) == V_VOID &&
1320 SPEC_NOUN (src) != V_VOID)
1323 if (SPEC_NOUN (dest) != V_VOID &&
1324 SPEC_NOUN (src) == V_VOID)
1327 /* char === to short */
1328 if (SPEC_NOUN (dest) == V_CHAR &&
1329 SPEC_NOUN (src) == V_INT &&
1331 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1333 if (SPEC_NOUN (src) == V_CHAR &&
1334 SPEC_NOUN (dest) == V_INT &&
1336 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1338 /* if they are both bitfields then if the lengths
1339 and starts don't match */
1340 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1341 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1342 SPEC_BSTR (dest) != SPEC_BSTR (src)))
1345 /* it is a specifier */
1346 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1348 if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1349 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1350 getSize (dest) == getSize (src))
1352 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1357 else if (IS_STRUCT (dest))
1359 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1364 if (SPEC_LONG (dest) != SPEC_LONG (src))
1367 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1370 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1376 /*------------------------------------------------------------------*/
1377 /* inCalleeSaveList - return 1 if found in calle save list */
1378 /*------------------------------------------------------------------*/
1380 inCalleeSaveList (char *s)
1384 for (i = 0; options.calleeSaves[i]; i++)
1385 if (strcmp (options.calleeSaves[i], s) == 0)
1391 /*-----------------------------------------------------------------*/
1392 /* aggregateArgToPointer: change an agggregate type function */
1393 /* argument to a pointer to that type. */
1394 /*-----------------------------------------------------------------*/
1396 aggregateArgToPointer (value * val)
1398 if (IS_AGGREGATE (val->type))
1400 /* if this is a structure */
1401 /* then we need to add a new link */
1402 if (IS_STRUCT (val->type))
1404 /* first lets add DECLARATOR type */
1405 sym_link *p = val->type;
1407 werror (W_STRUCT_AS_ARG, val->name);
1408 val->type = newLink ();
1409 val->type->next = p;
1412 /* change to a pointer depending on the */
1413 /* storage class specified */
1414 switch (SPEC_SCLS (val->etype))
1417 DCL_TYPE (val->type) = IPOINTER;
1420 DCL_TYPE (val->type) = PPOINTER;
1423 if (TARGET_IS_DS390)
1425 /* The AUTO and REGISTER classes should probably
1426 * also become generic pointers, but I haven't yet
1427 * devised a test case for that.
1429 DCL_TYPE (val->type) = GPOINTER;
1436 DCL_TYPE (val->type) = POINTER;
1439 DCL_TYPE (val->type) = CPOINTER;
1442 DCL_TYPE (val->type) = FPOINTER;
1445 DCL_TYPE (val->type) = EEPPOINTER;
1448 DCL_TYPE (val->type) = GPOINTER;
1451 /* is there is a symbol associated then */
1452 /* change the type of the symbol as well */
1455 val->sym->type = copyLinkChain (val->type);
1456 val->sym->etype = getSpec (val->sym->type);
1460 /*------------------------------------------------------------------*/
1461 /* checkFunction - does all kinds of check on a function */
1462 /*------------------------------------------------------------------*/
1464 checkFunction (symbol * sym)
1467 value *exargs, *acargs;
1470 /* if not type then some kind of error */
1474 /* if the function has no type then make it return int */
1475 if (!sym->type->next)
1476 sym->type->next = sym->etype = newIntLink ();
1478 /* function cannot return aggregate */
1479 if (IS_AGGREGATE (sym->type->next))
1481 werror (E_FUNC_AGGR, sym->name);
1485 /* function cannot return bit */
1486 if (IS_BITVAR (sym->type->next))
1488 werror (E_FUNC_BIT, sym->name);
1492 /* check if this function is defined as calleeSaves
1493 then mark it as such */
1494 sym->calleeSave = inCalleeSaveList (sym->name);
1496 /* if interrupt service routine */
1497 /* then it cannot have arguments */
1498 if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
1500 werror (E_INT_ARGS, sym->name);
1504 if (!(csym = findSym (SymbolTab, sym, sym->name)))
1505 return 1; /* not defined nothing more to check */
1507 /* check if body already present */
1508 if (csym && csym->fbody)
1510 werror (E_FUNC_BODY, sym->name);
1514 /* check the return value type */
1515 if (checkType (csym->type, sym->type) <= 0)
1517 werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1518 werror (E_CONTINUE, "previous defintion type ");
1519 printTypeChain (csym->type, stderr);
1520 fprintf (stderr, "\n");
1521 werror (E_CONTINUE, "current definition type ");
1522 printTypeChain (sym->type, stderr);
1523 fprintf (stderr, "\n");
1527 if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
1529 werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1533 if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
1535 werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1539 /* compare expected agrs with actual args */
1540 exargs = csym->args;
1543 /* for all the expected args do */
1546 exargs = exargs->next, acargs = acargs->next, argCnt++)
1549 /* If the actual argument is an array, any prototype
1550 * will have modified it to a pointer. Duplicate that
1553 if (IS_AGGREGATE (acargs->type))
1555 checkValue = copyValue (acargs);
1556 aggregateArgToPointer (checkValue);
1560 checkValue = acargs;
1563 if (checkType (exargs->type, checkValue->type) <= 0)
1565 werror (E_ARG_TYPE, argCnt);
1570 /* if one them ended we have a problem */
1571 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1572 (!exargs && acargs && !IS_VOID (acargs->type)))
1573 werror (E_ARG_COUNT);
1575 /* replace with this defition */
1576 sym->cdef = csym->cdef;
1577 deleteSym (SymbolTab, csym, csym->name);
1578 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
1579 if (IS_EXTERN (csym->etype) && !
1580 IS_EXTERN (sym->etype))
1582 addSet (&publics, sym);
1587 /*-----------------------------------------------------------------*/
1588 /* processFuncArgs - does some processing with function args */
1589 /*-----------------------------------------------------------------*/
1591 processFuncArgs (symbol * func, int ignoreName)
1596 /* if this function has variable argument list */
1597 /* then make the function a reentrant one */
1599 SPEC_RENT (func->etype) = 1;
1601 /* check if this function is defined as calleeSaves
1602 then mark it as such */
1603 func->calleeSave = inCalleeSaveList (func->name);
1605 val = func->args; /* loop thru all the arguments */
1607 /* if it is void then remove parameters */
1608 if (val && IS_VOID (val->type))
1614 /* reset regparm for the port */
1615 (*port->reset_regparms) ();
1616 /* if any of the arguments is an aggregate */
1617 /* change it to pointer to the same type */
1620 /* mark it as a register parameter if
1621 the function does not have VA_ARG
1622 and as port dictates */
1623 if (!func->hasVargs &&
1624 (*port->reg_parm) (val->type))
1626 SPEC_REGPARM (val->etype) = 1;
1629 if (IS_AGGREGATE (val->type))
1631 aggregateArgToPointer (val);
1637 /* if this is an internal generated function call */
1639 /* ignore --stack-auto for this one, we don't know how it is compiled */
1640 /* simply trust on --int-long-reent or --float-reent */
1641 if (IS_RENT(func->etype)) {
1645 /* if this function is reentrant or */
1646 /* automatics r 2b stacked then nothing */
1647 if (IS_RENT (func->etype) || options.stackAuto)
1656 /* if a symbolname is not given */
1657 /* synthesize a variable name */
1661 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1662 val->sym = newSymbol (val->name, 1);
1663 SPEC_OCLS (val->etype) = port->mem.default_local_map;
1664 val->sym->type = copyLinkChain (val->type);
1665 val->sym->etype = getSpec (val->sym->type);
1666 val->sym->_isparm = 1;
1667 strcpy (val->sym->rname, val->name);
1668 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1669 SPEC_STAT (func->etype);
1670 addSymChain (val->sym);
1673 else /* symbol name given create synth name */
1676 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1677 strcpy (val->sym->rname, val->name);
1678 val->sym->_isparm = 1;
1679 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1680 (options.model != MODEL_SMALL ? xdata : data);
1681 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1682 SPEC_STAT (func->etype);
1688 /*-----------------------------------------------------------------*/
1689 /* isSymbolEqual - compares two symbols return 1 if they match */
1690 /*-----------------------------------------------------------------*/
1692 isSymbolEqual (symbol * dest, symbol * src)
1694 /* if pointers match then equal */
1698 /* if one of them is null then don't match */
1702 /* if both of them have rname match on rname */
1703 if (dest->rname[0] && src->rname[0])
1704 return (!strcmp (dest->rname, src->rname));
1706 /* otherwise match on name */
1707 return (!strcmp (dest->name, src->name));
1710 void PT(sym_link *type)
1712 printTypeChain(type,0);
1714 /*-----------------------------------------------------------------*/
1715 /* printTypeChain - prints the type chain in human readable form */
1716 /*-----------------------------------------------------------------*/
1718 printTypeChain (sym_link * type, FILE * of)
1732 if (DCL_PTR_VOLATILE(type)) {
1733 fprintf (of, "volatile ");
1735 switch (DCL_TYPE (type))
1738 fprintf (of, "function ");
1741 fprintf (of, "_generic * ");
1742 if (DCL_PTR_CONST (type))
1743 fprintf (of, "const ");
1746 fprintf (of, "_code * ");
1747 if (DCL_PTR_CONST (type))
1748 fprintf (of, "const ");
1751 fprintf (of, "_far * ");
1752 if (DCL_PTR_CONST (type))
1753 fprintf (of, "const ");
1756 fprintf (of, "_eeprom * ");
1757 if (DCL_PTR_CONST (type))
1758 fprintf (of, "const ");
1762 fprintf (of, "_near * ");
1763 if (DCL_PTR_CONST (type))
1764 fprintf (of, "const ");
1767 fprintf (of, "_idata *");
1768 if (DCL_PTR_CONST (type))
1769 fprintf (of, "const ");
1772 fprintf (of, "_pdata *");
1773 if (DCL_PTR_CONST (type))
1774 fprintf (of, "const ");
1777 fprintf (of, " _unkown *");
1778 if (DCL_PTR_CONST (type))
1779 fprintf (of, "const ");
1782 fprintf (of, "array of ");
1788 if (SPEC_VOLATILE (type))
1789 fprintf (of, "volatile ");
1790 if (SPEC_USIGN (type))
1791 fprintf (of, "unsigned ");
1792 if (SPEC_CONST (type))
1793 fprintf (of, "const ");
1795 switch (SPEC_NOUN (type))
1799 fprintf (of, "long ");
1800 else if (IS_SHORT (type))
1801 fprintf (of, "short ");
1803 fprintf (of, "int ");
1807 fprintf (of, "char ");
1811 fprintf (of, "void ");
1815 fprintf (of, "float ");
1819 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1823 fprintf (of, "sbit ");
1827 fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1840 /*-----------------------------------------------------------------*/
1841 /* cdbTypeInfo - print the type information for debugger */
1842 /*-----------------------------------------------------------------*/
1844 cdbTypeInfo (sym_link * type, FILE * of)
1846 fprintf (of, "{%d}", getSize (type));
1851 switch (DCL_TYPE (type))
1854 fprintf (of, "DF,");
1857 fprintf (of, "DG,");
1860 fprintf (of, "DC,");
1863 fprintf (of, "DX,");
1866 fprintf (of, "DD,");
1869 fprintf (of, "DI,");
1872 fprintf (of, "DP,");
1875 fprintf (of, "DA,");
1878 fprintf (of, "DA%d,", DCL_ELEM (type));
1886 switch (SPEC_NOUN (type))
1891 else if (IS_SHORT (type))
1910 fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
1918 fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
1925 if (SPEC_USIGN (type))
1933 /*-----------------------------------------------------------------*/
1934 /* cdbSymbol - prints a symbol & its type information for debugger */
1935 /*-----------------------------------------------------------------*/
1937 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
1949 fprintf (of, "S:"); /* symbol record */
1950 /* if this is not a structure symbol then
1951 we need to figure out the scope information */
1957 if (IS_STATIC (sym->etype))
1958 fprintf (of, "F%s$", moduleName); /* scope is file */
1960 fprintf (of, "G$"); /* scope is global */
1963 /* symbol is local */
1964 fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
1967 fprintf (of, "S$"); /* scope is structure */
1969 /* print the name, & mangled name */
1970 fprintf (of, "%s$%d$%d(", sym->name,
1971 sym->level, sym->block);
1973 cdbTypeInfo (sym->type, of);
1976 /* print the address space */
1977 map = SPEC_OCLS (sym->etype);
1978 fprintf (of, "%c,%d,%d",
1979 (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
1981 /* if assigned to registers then output register names */
1982 /* if this is a function then print
1983 if is it an interrupt routine & interrupt number
1984 and the register bank it is using */
1986 fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
1987 SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
1988 /* alternate location to find this symbol @ : eg registers
1995 /*-----------------------------------------------------------------*/
1996 /* cdbStruct - print a structure for debugger */
1997 /*-----------------------------------------------------------------*/
1999 cdbStruct (structdef * sdef, int block, FILE * of,
2000 int inStruct, char *tag)
2005 /* if block # then must have function scope */
2006 fprintf (of, "F%s$", moduleName);
2007 fprintf (of, "%s[", (tag ? tag : sdef->tag));
2008 for (sym = sdef->fields; sym; sym = sym->next)
2010 fprintf (of, "({%d}", sym->offset);
2011 cdbSymbol (sym, of, TRUE, FALSE);
2019 /*------------------------------------------------------------------*/
2020 /* cdbStructBlock - calls struct printing for a blcks */
2021 /*------------------------------------------------------------------*/
2023 cdbStructBlock (int block, FILE * of)
2026 bucket **table = StructTab;
2030 /* go thru the entire table */
2031 for (i = 0; i < 256; i++)
2033 for (chain = table[i]; chain; chain = chain->next)
2035 if (chain->block >= block)
2037 cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2043 /*-----------------------------------------------------------------*/
2044 /* powof2 - returns power of two for the number if number is pow 2 */
2045 /*-----------------------------------------------------------------*/
2047 powof2 (unsigned long num)
2060 if (n1s > 1 || nshifts == 0)
2076 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2077 symbol *__muldiv[3][3][2];
2078 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2079 sym_link *__multypes[3][2];
2080 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2081 symbol *__conv[2][3][2];
2083 sym_link *floatType;
2086 _makeRegParam (symbol * sym)
2090 val = sym->args; /* loop thru all the arguments */
2092 /* reset regparm for the port */
2093 (*port->reset_regparms) ();
2096 SPEC_REGPARM (val->etype) = 1;
2101 /*-----------------------------------------------------------------*/
2102 /* initCSupport - create functions for C support routines */
2103 /*-----------------------------------------------------------------*/
2107 const char *smuldivmod[] =
2111 const char *sbwd[] =
2113 "char", "int", "long"
2120 int bwd, su, muldivmod, tofrom;
2122 floatType = newFloatLink ();
2124 for (bwd = 0; bwd < 3; bwd++)
2141 __multypes[bwd][0] = l;
2142 __multypes[bwd][1] = copyLinkChain (l);
2143 SPEC_USIGN (__multypes[bwd][1]) = 1;
2146 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2147 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2148 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2149 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2150 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2151 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2152 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2153 __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2154 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2155 __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2157 for (tofrom = 0; tofrom < 2; tofrom++)
2159 for (bwd = 0; bwd < 3; bwd++)
2161 for (su = 0; su < 2; su++)
2165 sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2166 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2170 sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2171 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2177 for (muldivmod = 0; muldivmod < 3; muldivmod++)
2179 for (bwd = 0; bwd < 3; bwd++)
2181 for (su = 0; su < 2; su++)
2183 sprintf (buffer, "_%s%s%s",
2184 smuldivmod[muldivmod],
2187 __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2188 SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2189 if (bwd < port->muldiv.force_reg_param_below)
2190 _makeRegParam (__muldiv[muldivmod][bwd][su]);