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 &&
1101 !IS_STATIC(sym->etype))
1103 if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
1105 SPEC_SCLS (sym->etype) = (options.useXstack ?
1106 S_XSTACK : S_STACK);
1110 /* hack-o-matic! I see no reason why the useXstack option should ever
1111 * control this allcoation, but the code was originally that way, and
1112 * changing it for non-390 ports breaks the compiler badly.
1114 bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
1115 SPEC_SCLS (sym->etype) = (useXdata ?
1121 /*------------------------------------------------------------------*/
1122 /* changePointer - change pointer to functions */
1123 /*------------------------------------------------------------------*/
1125 changePointer (symbol * sym)
1129 /* go thru the chain of declarations */
1130 /* if we find a pointer to a function */
1131 /* unconditionally change it to a ptr */
1133 for (p = sym->type; p; p = p->next)
1135 if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1136 DCL_TYPE (p) = GPOINTER;
1137 if (IS_PTR (p) && IS_FUNC (p->next))
1138 DCL_TYPE (p) = CPOINTER;
1142 /*------------------------------------------------------------------*/
1143 /* checkDecl - does semantic validation of a declaration */
1144 /*------------------------------------------------------------------*/
1146 checkDecl (symbol * sym)
1149 checkSClass (sym); /* check the storage class */
1150 changePointer (sym); /* change pointers if required */
1152 /* if this is an array without any dimension
1153 then update the dimension from the initial value */
1154 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1155 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1160 /*------------------------------------------------------------------*/
1161 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1162 /*------------------------------------------------------------------*/
1164 copyLinkChain (sym_link * p)
1166 sym_link *head, *curr, *loop;
1169 head = loop = (curr ? newLink () : (void *) NULL);
1172 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
1173 loop->next = (curr->next ? newLink () : (void *) NULL);
1182 /*------------------------------------------------------------------*/
1183 /* cleanUpBlock - cleansup the symbol table specified for all the */
1184 /* symbols in the given block */
1185 /*------------------------------------------------------------------*/
1187 cleanUpBlock (bucket ** table, int block)
1192 /* go thru the entire table */
1193 for (i = 0; i < 256; i++)
1195 for (chain = table[i]; chain; chain = chain->next)
1197 if (chain->block >= block)
1199 deleteSym (table, chain->sym, chain->name);
1205 /*------------------------------------------------------------------*/
1206 /* cleanUpLevel - cleansup the symbol table specified for all the */
1207 /* symbols in the given level */
1208 /*------------------------------------------------------------------*/
1210 cleanUpLevel (bucket ** table, int level)
1215 /* go thru the entire table */
1216 for (i = 0; i < 256; i++)
1218 for (chain = table[i]; chain; chain = chain->next)
1220 if (chain->level >= level)
1222 deleteSym (table, chain->sym, chain->name);
1228 /*------------------------------------------------------------------*/
1229 /* computeType - computes the resultant type from two types */
1230 /*------------------------------------------------------------------*/
1232 computeType (sym_link * type1, sym_link * type2)
1236 sym_link *etype1 = getSpec (type1);
1237 sym_link *etype2 = getSpec (type2);
1239 /* if one of them is a float then result is a float */
1240 /* here we assume that the types passed are okay */
1241 /* and can be cast to one another */
1242 /* which ever is greater in size */
1243 if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1244 rType = newFloatLink ();
1246 /* if only one of them is a bit variable
1247 then the other one prevails */
1248 if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1249 rType = copyLinkChain (type2);
1250 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1251 rType = copyLinkChain (type1);
1253 /* if one of them is a pointer then that
1256 rType = copyLinkChain (type1);
1257 else if (IS_PTR (type2))
1258 rType = copyLinkChain (type2);
1259 else if (getSize (type1) > getSize (type2))
1260 rType = copyLinkChain (type1);
1262 rType = copyLinkChain (type2);
1264 reType = getSpec (rType);
1266 /* if either of them unsigned then make this unsigned */
1267 if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
1268 SPEC_USIGN (reType) = 1;
1270 /* if result is a literal then make not so */
1271 if (IS_LITERAL (reType))
1272 SPEC_SCLS (reType) = S_REGISTER;
1277 /*------------------------------------------------------------------*/
1278 /* checkType - will do type check return 1 if match */
1279 /*------------------------------------------------------------------*/
1281 checkType (sym_link * dest, sym_link * src)
1292 /* if dest is a declarator then */
1297 if (DCL_TYPE (src) == DCL_TYPE (dest))
1298 return checkType (dest->next, src->next);
1299 else if (IS_PTR (src) && IS_PTR (dest))
1301 else if (IS_PTR (dest) && IS_ARRAY (src))
1303 else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1304 return -1 * checkType (dest->next, src);
1308 else if (IS_PTR (dest) && IS_INTEGRAL (src))
1314 /* if one is a specifier and the other is not */
1315 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1316 (IS_SPEC (dest) && !IS_SPEC (src)))
1319 /* if one of them is a void then ok */
1320 if (SPEC_NOUN (dest) == V_VOID &&
1321 SPEC_NOUN (src) != V_VOID)
1324 if (SPEC_NOUN (dest) != V_VOID &&
1325 SPEC_NOUN (src) == V_VOID)
1328 /* char === to short */
1329 if (SPEC_NOUN (dest) == V_CHAR &&
1330 SPEC_NOUN (src) == V_INT &&
1332 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1334 if (SPEC_NOUN (src) == V_CHAR &&
1335 SPEC_NOUN (dest) == V_INT &&
1337 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1339 /* if they are both bitfields then if the lengths
1340 and starts don't match */
1341 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1342 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1343 SPEC_BSTR (dest) != SPEC_BSTR (src)))
1346 /* it is a specifier */
1347 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1349 if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1350 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1351 getSize (dest) == getSize (src))
1353 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1358 else if (IS_STRUCT (dest))
1360 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1365 if (SPEC_LONG (dest) != SPEC_LONG (src))
1368 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1371 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1377 /*------------------------------------------------------------------*/
1378 /* inCalleeSaveList - return 1 if found in calle save list */
1379 /*------------------------------------------------------------------*/
1381 inCalleeSaveList (char *s)
1385 for (i = 0; options.calleeSaves[i]; i++)
1386 if (strcmp (options.calleeSaves[i], s) == 0)
1392 /*-----------------------------------------------------------------*/
1393 /* aggregateArgToPointer: change an agggregate type function */
1394 /* argument to a pointer to that type. */
1395 /*-----------------------------------------------------------------*/
1397 aggregateArgToPointer (value * val)
1399 if (IS_AGGREGATE (val->type))
1401 /* if this is a structure */
1402 /* then we need to add a new link */
1403 if (IS_STRUCT (val->type))
1405 /* first lets add DECLARATOR type */
1406 sym_link *p = val->type;
1408 werror (W_STRUCT_AS_ARG, val->name);
1409 val->type = newLink ();
1410 val->type->next = p;
1413 /* change to a pointer depending on the */
1414 /* storage class specified */
1415 switch (SPEC_SCLS (val->etype))
1418 DCL_TYPE (val->type) = IPOINTER;
1421 DCL_TYPE (val->type) = PPOINTER;
1424 if (TARGET_IS_DS390)
1426 /* The AUTO and REGISTER classes should probably
1427 * also become generic pointers, but I haven't yet
1428 * devised a test case for that.
1430 DCL_TYPE (val->type) = GPOINTER;
1437 DCL_TYPE (val->type) = POINTER;
1440 DCL_TYPE (val->type) = CPOINTER;
1443 DCL_TYPE (val->type) = FPOINTER;
1446 DCL_TYPE (val->type) = EEPPOINTER;
1449 DCL_TYPE (val->type) = GPOINTER;
1452 /* is there is a symbol associated then */
1453 /* change the type of the symbol as well */
1456 val->sym->type = copyLinkChain (val->type);
1457 val->sym->etype = getSpec (val->sym->type);
1461 /*------------------------------------------------------------------*/
1462 /* checkFunction - does all kinds of check on a function */
1463 /*------------------------------------------------------------------*/
1465 checkFunction (symbol * sym)
1468 value *exargs, *acargs;
1471 /* if not type then some kind of error */
1475 /* if the function has no type then make it return int */
1476 if (!sym->type->next)
1477 sym->type->next = sym->etype = newIntLink ();
1479 /* function cannot return aggregate */
1480 if (IS_AGGREGATE (sym->type->next))
1482 werror (E_FUNC_AGGR, sym->name);
1486 /* function cannot return bit */
1487 if (IS_BITVAR (sym->type->next))
1489 werror (E_FUNC_BIT, sym->name);
1493 /* check if this function is defined as calleeSaves
1494 then mark it as such */
1495 sym->calleeSave = inCalleeSaveList (sym->name);
1497 /* if interrupt service routine */
1498 /* then it cannot have arguments */
1499 if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
1501 werror (E_INT_ARGS, sym->name);
1505 if (!(csym = findSym (SymbolTab, sym, sym->name)))
1506 return 1; /* not defined nothing more to check */
1508 /* check if body already present */
1509 if (csym && csym->fbody)
1511 werror (E_FUNC_BODY, sym->name);
1515 /* check the return value type */
1516 if (checkType (csym->type, sym->type) <= 0)
1518 werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1519 werror (E_CONTINUE, "previous defintion type ");
1520 printTypeChain (csym->type, stderr);
1521 fprintf (stderr, "\n");
1522 werror (E_CONTINUE, "current definition type ");
1523 printTypeChain (sym->type, stderr);
1524 fprintf (stderr, "\n");
1528 if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
1530 werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1534 if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
1536 werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1540 /* compare expected agrs with actual args */
1541 exargs = csym->args;
1544 /* for all the expected args do */
1547 exargs = exargs->next, acargs = acargs->next, argCnt++)
1550 /* If the actual argument is an array, any prototype
1551 * will have modified it to a pointer. Duplicate that
1554 if (IS_AGGREGATE (acargs->type))
1556 checkValue = copyValue (acargs);
1557 aggregateArgToPointer (checkValue);
1561 checkValue = acargs;
1564 if (checkType (exargs->type, checkValue->type) <= 0)
1566 werror (E_ARG_TYPE, argCnt);
1571 /* if one them ended we have a problem */
1572 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1573 (!exargs && acargs && !IS_VOID (acargs->type)))
1574 werror (E_ARG_COUNT);
1576 /* replace with this defition */
1577 sym->cdef = csym->cdef;
1578 deleteSym (SymbolTab, csym, csym->name);
1579 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
1580 if (IS_EXTERN (csym->etype) && !
1581 IS_EXTERN (sym->etype))
1583 addSet (&publics, sym);
1588 /*-----------------------------------------------------------------*/
1589 /* processFuncArgs - does some processing with function args */
1590 /*-----------------------------------------------------------------*/
1592 processFuncArgs (symbol * func, int ignoreName)
1597 /* if this function has variable argument list */
1598 /* then make the function a reentrant one */
1600 SPEC_RENT (func->etype) = 1;
1602 /* check if this function is defined as calleeSaves
1603 then mark it as such */
1604 func->calleeSave = inCalleeSaveList (func->name);
1606 val = func->args; /* loop thru all the arguments */
1608 /* if it is void then remove parameters */
1609 if (val && IS_VOID (val->type))
1615 /* reset regparm for the port */
1616 (*port->reset_regparms) ();
1617 /* if any of the arguments is an aggregate */
1618 /* change it to pointer to the same type */
1621 /* mark it as a register parameter if
1622 the function does not have VA_ARG
1623 and as port dictates */
1624 if (!func->hasVargs &&
1625 (*port->reg_parm) (val->type))
1627 SPEC_REGPARM (val->etype) = 1;
1630 if (IS_AGGREGATE (val->type))
1632 aggregateArgToPointer (val);
1638 /* if this is an internal generated function call */
1640 /* ignore --stack-auto for this one, we don't know how it is compiled */
1641 /* simply trust on --int-long-reent or --float-reent */
1642 if (IS_RENT(func->etype)) {
1646 /* if this function is reentrant or */
1647 /* automatics r 2b stacked then nothing */
1648 if (IS_RENT (func->etype) || options.stackAuto)
1657 /* if a symbolname is not given */
1658 /* synthesize a variable name */
1662 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1663 val->sym = newSymbol (val->name, 1);
1664 SPEC_OCLS (val->etype) = port->mem.default_local_map;
1665 val->sym->type = copyLinkChain (val->type);
1666 val->sym->etype = getSpec (val->sym->type);
1667 val->sym->_isparm = 1;
1668 strcpy (val->sym->rname, val->name);
1669 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1670 SPEC_STAT (func->etype);
1671 addSymChain (val->sym);
1674 else /* symbol name given create synth name */
1677 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1678 strcpy (val->sym->rname, val->name);
1679 val->sym->_isparm = 1;
1680 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1681 (options.model != MODEL_SMALL ? xdata : data);
1682 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1683 SPEC_STAT (func->etype);
1689 /*-----------------------------------------------------------------*/
1690 /* isSymbolEqual - compares two symbols return 1 if they match */
1691 /*-----------------------------------------------------------------*/
1693 isSymbolEqual (symbol * dest, symbol * src)
1695 /* if pointers match then equal */
1699 /* if one of them is null then don't match */
1703 /* if both of them have rname match on rname */
1704 if (dest->rname[0] && src->rname[0])
1705 return (!strcmp (dest->rname, src->rname));
1707 /* otherwise match on name */
1708 return (!strcmp (dest->name, src->name));
1711 void PT(sym_link *type)
1713 printTypeChain(type,0);
1715 /*-----------------------------------------------------------------*/
1716 /* printTypeChain - prints the type chain in human readable form */
1717 /*-----------------------------------------------------------------*/
1719 printTypeChain (sym_link * type, FILE * of)
1733 if (DCL_PTR_VOLATILE(type)) {
1734 fprintf (of, "volatile ");
1736 switch (DCL_TYPE (type))
1739 fprintf (of, "function ");
1742 fprintf (of, "_generic * ");
1743 if (DCL_PTR_CONST (type))
1744 fprintf (of, "const ");
1747 fprintf (of, "_code * ");
1748 if (DCL_PTR_CONST (type))
1749 fprintf (of, "const ");
1752 fprintf (of, "_far * ");
1753 if (DCL_PTR_CONST (type))
1754 fprintf (of, "const ");
1757 fprintf (of, "_eeprom * ");
1758 if (DCL_PTR_CONST (type))
1759 fprintf (of, "const ");
1763 fprintf (of, "_near * ");
1764 if (DCL_PTR_CONST (type))
1765 fprintf (of, "const ");
1768 fprintf (of, "_idata *");
1769 if (DCL_PTR_CONST (type))
1770 fprintf (of, "const ");
1773 fprintf (of, "_pdata *");
1774 if (DCL_PTR_CONST (type))
1775 fprintf (of, "const ");
1778 fprintf (of, " _unkown *");
1779 if (DCL_PTR_CONST (type))
1780 fprintf (of, "const ");
1783 fprintf (of, "array of ");
1789 if (SPEC_VOLATILE (type))
1790 fprintf (of, "volatile ");
1791 if (SPEC_USIGN (type))
1792 fprintf (of, "unsigned ");
1793 if (SPEC_CONST (type))
1794 fprintf (of, "const ");
1796 switch (SPEC_NOUN (type))
1800 fprintf (of, "long ");
1801 else if (IS_SHORT (type))
1802 fprintf (of, "short ");
1804 fprintf (of, "int ");
1808 fprintf (of, "char ");
1812 fprintf (of, "void ");
1816 fprintf (of, "float ");
1820 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1824 fprintf (of, "sbit ");
1828 fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1841 /*-----------------------------------------------------------------*/
1842 /* cdbTypeInfo - print the type information for debugger */
1843 /*-----------------------------------------------------------------*/
1845 cdbTypeInfo (sym_link * type, FILE * of)
1847 fprintf (of, "{%d}", getSize (type));
1852 switch (DCL_TYPE (type))
1855 fprintf (of, "DF,");
1858 fprintf (of, "DG,");
1861 fprintf (of, "DC,");
1864 fprintf (of, "DX,");
1867 fprintf (of, "DD,");
1870 fprintf (of, "DI,");
1873 fprintf (of, "DP,");
1876 fprintf (of, "DA,");
1879 fprintf (of, "DA%d,", DCL_ELEM (type));
1887 switch (SPEC_NOUN (type))
1892 else if (IS_SHORT (type))
1911 fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
1919 fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
1926 if (SPEC_USIGN (type))
1934 /*-----------------------------------------------------------------*/
1935 /* cdbSymbol - prints a symbol & its type information for debugger */
1936 /*-----------------------------------------------------------------*/
1938 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
1950 fprintf (of, "S:"); /* symbol record */
1951 /* if this is not a structure symbol then
1952 we need to figure out the scope information */
1958 if (IS_STATIC (sym->etype))
1959 fprintf (of, "F%s$", moduleName); /* scope is file */
1961 fprintf (of, "G$"); /* scope is global */
1964 /* symbol is local */
1965 fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
1968 fprintf (of, "S$"); /* scope is structure */
1970 /* print the name, & mangled name */
1971 fprintf (of, "%s$%d$%d(", sym->name,
1972 sym->level, sym->block);
1974 cdbTypeInfo (sym->type, of);
1977 /* print the address space */
1978 map = SPEC_OCLS (sym->etype);
1979 fprintf (of, "%c,%d,%d",
1980 (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
1982 /* if assigned to registers then output register names */
1983 /* if this is a function then print
1984 if is it an interrupt routine & interrupt number
1985 and the register bank it is using */
1987 fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
1988 SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
1989 /* alternate location to find this symbol @ : eg registers
1996 /*-----------------------------------------------------------------*/
1997 /* cdbStruct - print a structure for debugger */
1998 /*-----------------------------------------------------------------*/
2000 cdbStruct (structdef * sdef, int block, FILE * of,
2001 int inStruct, char *tag)
2006 /* if block # then must have function scope */
2007 fprintf (of, "F%s$", moduleName);
2008 fprintf (of, "%s[", (tag ? tag : sdef->tag));
2009 for (sym = sdef->fields; sym; sym = sym->next)
2011 fprintf (of, "({%d}", sym->offset);
2012 cdbSymbol (sym, of, TRUE, FALSE);
2020 /*------------------------------------------------------------------*/
2021 /* cdbStructBlock - calls struct printing for a blcks */
2022 /*------------------------------------------------------------------*/
2024 cdbStructBlock (int block, FILE * of)
2027 bucket **table = StructTab;
2031 /* go thru the entire table */
2032 for (i = 0; i < 256; i++)
2034 for (chain = table[i]; chain; chain = chain->next)
2036 if (chain->block >= block)
2038 cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2044 /*-----------------------------------------------------------------*/
2045 /* powof2 - returns power of two for the number if number is pow 2 */
2046 /*-----------------------------------------------------------------*/
2048 powof2 (unsigned long num)
2061 if (n1s > 1 || nshifts == 0)
2077 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2078 symbol *__muldiv[3][3][2];
2079 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2080 sym_link *__multypes[3][2];
2081 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2082 symbol *__conv[2][3][2];
2084 sym_link *floatType;
2087 _makeRegParam (symbol * sym)
2091 val = sym->args; /* loop thru all the arguments */
2093 /* reset regparm for the port */
2094 (*port->reset_regparms) ();
2097 SPEC_REGPARM (val->etype) = 1;
2102 /*-----------------------------------------------------------------*/
2103 /* initCSupport - create functions for C support routines */
2104 /*-----------------------------------------------------------------*/
2108 const char *smuldivmod[] =
2112 const char *sbwd[] =
2114 "char", "int", "long"
2121 int bwd, su, muldivmod, tofrom;
2123 floatType = newFloatLink ();
2125 for (bwd = 0; bwd < 3; bwd++)
2142 __multypes[bwd][0] = l;
2143 __multypes[bwd][1] = copyLinkChain (l);
2144 SPEC_USIGN (__multypes[bwd][1]) = 1;
2147 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2148 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2149 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2150 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2151 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2152 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2153 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2154 __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2155 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2156 __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2158 for (tofrom = 0; tofrom < 2; tofrom++)
2160 for (bwd = 0; bwd < 3; bwd++)
2162 for (su = 0; su < 2; su++)
2166 sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2167 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2171 sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2172 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2178 for (muldivmod = 0; muldivmod < 3; muldivmod++)
2180 for (bwd = 0; bwd < 3; bwd++)
2182 for (su = 0; su < 2; su++)
2184 sprintf (buffer, "_%s%s%s",
2185 smuldivmod[muldivmod],
2188 __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2189 SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2190 if (bwd < port->muldiv.force_reg_param_below)
2191 _makeRegParam (__muldiv[muldivmod][bwd][su]);