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) || (SPEC_SCLS(dest) == S_CONSTANT && SPEC_SCLS (src)))
439 SPEC_SCLS (dest) = SPEC_SCLS (src);
440 /* special case for const */
441 /* copy all the specifications */
442 SPEC_LONG (dest) |= SPEC_LONG (src);
443 SPEC_SHORT (dest) |= SPEC_SHORT (src);
444 SPEC_USIGN (dest) |= SPEC_USIGN (src);
445 SPEC_STAT (dest) |= SPEC_STAT (src);
446 SPEC_EXTR (dest) |= SPEC_EXTR (src);
447 SPEC_ABSA (dest) |= SPEC_ABSA (src);
448 SPEC_RENT (dest) |= SPEC_RENT (src);
449 SPEC_INTN (dest) |= SPEC_INTN (src);
450 SPEC_BANK (dest) |= SPEC_BANK (src);
451 SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src);
452 SPEC_CRTCL (dest) |= SPEC_CRTCL (src);
453 SPEC_ADDR (dest) |= SPEC_ADDR (src);
454 SPEC_OCLS (dest) = SPEC_OCLS (src);
455 SPEC_BLEN (dest) |= SPEC_BLEN (src);
456 SPEC_BSTR (dest) |= SPEC_BSTR (src);
457 SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src);
458 SPEC_NONBANKED (dest) |= SPEC_NONBANKED (src);
460 if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
461 SPEC_STRUCT (dest) = SPEC_STRUCT (src);
466 /*------------------------------------------------------------------*/
467 /* cloneSpec - copies the entire spec and returns a new spec */
468 /*------------------------------------------------------------------*/
470 cloneSpec (sym_link * src)
474 /* go thru chain till we find the specifier */
475 while (src && src->class != SPECIFIER)
479 memcpy (spec, src, sizeof (sym_link));
483 /*------------------------------------------------------------------*/
484 /* genSymName - generates and returns a name used for anonymous vars */
485 /*------------------------------------------------------------------*/
487 genSymName (int level)
489 static int gCount = 0;
490 static char gname[SDCC_NAME_MAX + 1];
492 sprintf (gname, "__%04d%04d", level, gCount++);
496 /*------------------------------------------------------------------*/
497 /* getSpec - returns the specifier part from a declaration chain */
498 /*------------------------------------------------------------------*/
500 getSpec (sym_link * p)
505 while (p && !(IS_SPEC (p)))
511 /*------------------------------------------------------------------*/
512 /* newCharLink() - creates an int type */
513 /*------------------------------------------------------------------*/
520 p->class = SPECIFIER;
521 SPEC_NOUN (p) = V_CHAR;
526 /*------------------------------------------------------------------*/
527 /* newFloatLink - a new Float type */
528 /*------------------------------------------------------------------*/
535 p->class = SPECIFIER;
536 SPEC_NOUN (p) = V_FLOAT;
541 /*------------------------------------------------------------------*/
542 /* newLongLink() - new long type */
543 /*------------------------------------------------------------------*/
550 p->class = SPECIFIER;
551 SPEC_NOUN (p) = V_INT;
557 /*------------------------------------------------------------------*/
558 /* newIntLink() - creates an int type */
559 /*------------------------------------------------------------------*/
566 p->class = SPECIFIER;
567 SPEC_NOUN (p) = V_INT;
572 /*------------------------------------------------------------------*/
573 /* getSize - returns size of a type chain in bits */
574 /*------------------------------------------------------------------*/
576 getSize (sym_link * p)
578 /* if nothing return 0 */
582 { /* if this is the specifier then */
583 switch (SPEC_NOUN (p))
584 { /* depending on the specifier type */
586 return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE));
594 return SPEC_STRUCT (p)->size;
600 return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
606 /* this is a specifier */
607 switch (DCL_TYPE (p))
612 return DCL_ELEM (p) * getSize (p->next);
629 /*------------------------------------------------------------------*/
630 /* bitsForType - returns # of bits required to store this type */
631 /*------------------------------------------------------------------*/
633 bitsForType (sym_link * p)
635 /* if nothing return 0 */
640 { /* if this is the specifier then */
642 switch (SPEC_NOUN (p))
643 { /* depending on the specifier type */
645 return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8));
647 return FLOATSIZE * 8;
653 return SPEC_STRUCT (p)->size * 8;
659 return SPEC_BLEN (p);
665 /* this is a specifier */
666 switch (DCL_TYPE (p))
671 return DCL_ELEM (p) * getSize (p->next) * 8;
675 return (PTRSIZE * 8);
679 return (FPTRSIZE * 8);
681 return (GPTRSIZE * 8);
688 /*------------------------------------------------------------------*/
689 /* copySymbolChain - copies a symbol chain */
690 /*------------------------------------------------------------------*/
692 copySymbolChain (symbol * src)
699 dest = copySymbol (src);
700 dest->next = copySymbolChain (src->next);
704 /*------------------------------------------------------------------*/
705 /* copySymbol - makes a copy of a symbol */
706 /*------------------------------------------------------------------*/
708 copySymbol (symbol * src)
715 dest = newSymbol (src->name, src->level);
716 memcpy (dest, src, sizeof (symbol));
717 dest->level = src->level;
718 dest->block = src->block;
719 dest->ival = copyIlist (src->ival);
720 dest->type = copyLinkChain (src->type);
721 dest->etype = getSpec (dest->type);
723 dest->args = copyValueChain (src->args);
724 dest->key = src->key;
725 dest->calleeSave = src->calleeSave;
726 dest->allocreq = src->allocreq;
730 /*------------------------------------------------------------------*/
731 /* reverseSyms - reverses the links for a symbol chain */
732 /*------------------------------------------------------------------*/
734 reverseSyms (symbol * sym)
736 symbol *prev, *curr, *next;
751 sym->next = (void *) NULL;
755 /*------------------------------------------------------------------*/
756 /* reverseLink - reverses the links for a type chain */
757 /*------------------------------------------------------------------*/
759 reverseLink (sym_link * type)
761 sym_link *prev, *curr, *next;
776 type->next = (void *) NULL;
780 /*------------------------------------------------------------------*/
781 /* addSymChain - adds a symbol chain to the symboltable */
782 /*------------------------------------------------------------------*/
784 addSymChain (symbol * symHead)
786 symbol *sym = symHead;
789 for (; sym != NULL; sym = sym->next)
792 /* if already exists in the symbol table then check if
793 the previous was an extern definition if yes then
794 then check if the type match, if the types match then
795 delete the current entry and add the new entry */
796 if ((csym = findSymWithLevel (SymbolTab, sym)) &&
797 csym->level == sym->level)
800 /* previous definition extern ? */
801 if (IS_EXTERN (csym->etype))
803 /* do types match ? */
804 if (checkType (csym->type, sym->type) != 1)
806 werror (E_DUPLICATE, csym->name);
808 /* delete current entry */
809 deleteSym (SymbolTab, csym, csym->name);
811 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
813 else /* not extern */
814 werror (E_DUPLICATE, sym->name);
818 /* check if previously defined */
819 if (csym && csym->level == sym->level)
821 /* if the previous one was declared as extern */
822 /* then check the type with the current one */
823 if (IS_EXTERN (csym->etype))
825 if (checkType (csym->type, sym->type) <= 0)
826 werror (W_EXTERN_MISMATCH, csym->name);
830 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
835 /*------------------------------------------------------------------*/
836 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
837 /*------------------------------------------------------------------*/
839 funcInChain (sym_link * lnk)
850 /*------------------------------------------------------------------*/
851 /* structElemType - returns the type info of a sturct member */
852 /*------------------------------------------------------------------*/
854 structElemType (sym_link * stype, value * id, value ** argsp)
856 symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL);
857 sym_link *type, *etype;
858 sym_link *petype = getSpec (stype);
863 /* look for the id */
866 if (strcmp (fields->rname, id->name) == 0)
870 *argsp = fields->args;
872 type = copyLinkChain (fields->type);
873 etype = getSpec (type);
874 SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ?
875 SPEC_SCLS (etype) : SPEC_SCLS (petype));
878 fields = fields->next;
880 werror (E_NOT_MEMBER, id->name);
885 /*------------------------------------------------------------------*/
886 /* getStructElement - returns element of a tructure definition */
887 /*------------------------------------------------------------------*/
889 getStructElement (structdef * sdef, symbol * sym)
893 for (field = sdef->fields; field; field = field->next)
894 if (strcmp (field->name, sym->name) == 0)
897 werror (E_NOT_MEMBER, sym->name);
902 /*------------------------------------------------------------------*/
903 /* compStructSize - computes the size of a structure */
904 /*------------------------------------------------------------------*/
906 compStructSize (int su, structdef * sdef)
908 int sum = 0, usum = 0;
912 /* for the identifiers */
916 /* create the internal name for this variable */
917 sprintf (loop->rname, "_%s", loop->name);
918 loop->offset = (su == UNION ? sum = 0 : sum);
919 SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0);
921 /* if this is a bit field */
924 /* change it to a unsigned bit */
925 SPEC_NOUN (loop->etype) = V_BIT;
926 SPEC_USIGN (loop->etype) = 1;
927 /* check if this fit into the remaining */
928 /* bits of this byte else align it to the */
929 /* next byte boundary */
930 if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) {
931 SPEC_BSTR (loop->etype) = bitOffset;
932 if ((bitOffset += (loop->bitVar % 8)) == 8)
935 else /* does not fit */ {
937 SPEC_BSTR (loop->etype) = bitOffset;
938 sum += (loop->bitVar / 8);
939 bitOffset += (loop->bitVar % 8);
941 /* if this is the last field then pad */
942 if (!loop->next && bitOffset && bitOffset != 8) {
949 sum += getSize (loop->type);
952 /* if function then do the arguments for it */
953 if (funcInChain (loop->type)) {
954 processFuncArgs (loop, 1);
959 /* if this is not a bitfield but the */
960 /* previous one was and did not take */
961 /* the whole byte then pad the rest */
962 if ((loop && !loop->bitVar) && bitOffset) {
967 /* if union then size = sizeof larget field */
969 usum = max (usum, sum);
973 return (su == UNION ? usum : sum);
976 /*------------------------------------------------------------------*/
977 /* checkSClass - check the storage class specification */
978 /*------------------------------------------------------------------*/
980 checkSClass (symbol * sym)
982 /* type is literal can happen foe enums change
984 if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
985 SPEC_SCLS (sym->etype) = S_AUTO;
987 /* if sfr or sbit then must also be */
988 /* volatile the initial value will be xlated */
989 /* to an absolute address */
990 if (SPEC_SCLS (sym->etype) == S_SBIT ||
991 SPEC_SCLS (sym->etype) == S_SFR)
993 SPEC_VOLATILE (sym->etype) = 1;
994 /* if initial value given */
997 SPEC_ABSA (sym->etype) = 1;
998 SPEC_ADDR (sym->etype) =
999 (int) list2int (sym->ival);
1004 /* if absolute address given then it mark it as
1006 if (IS_ABSOLUTE (sym->etype))
1007 SPEC_VOLATILE (sym->etype) = 1;
1009 /* global variables declared const put into code */
1010 if (sym->level == 0 &&
1011 SPEC_SCLS (sym->etype) == S_CONSTANT)
1013 SPEC_SCLS (sym->etype) = S_CODE;
1014 SPEC_CONST (sym->etype) = 1;
1017 /* global variable in code space is a constant */
1018 if (sym->level == 0 &&
1019 SPEC_SCLS (sym->etype) == S_CODE &&
1021 SPEC_CONST (sym->etype) = 1;
1024 /* if bit variable then no storage class can be */
1025 /* specified since bit is already a storage */
1026 if (IS_BITVAR (sym->etype) &&
1027 (SPEC_SCLS (sym->etype) != S_FIXED &&
1028 SPEC_SCLS (sym->etype) != S_SBIT &&
1029 SPEC_SCLS (sym->etype) != S_BIT)
1032 werror (E_BITVAR_STORAGE, sym->name);
1033 SPEC_SCLS (sym->etype) = S_FIXED;
1036 /* extern variables cannot be initialized */
1037 if (IS_EXTERN (sym->etype) && sym->ival)
1039 werror (E_EXTERN_INIT, sym->name);
1043 /* if this is an automatic symbol then */
1044 /* storage class will be ignored and */
1045 /* symbol will be allocated on stack/ */
1046 /* data depending on flag */
1048 (options.stackAuto || reentrant) &&
1049 (SPEC_SCLS (sym->etype) != S_AUTO &&
1050 SPEC_SCLS (sym->etype) != S_FIXED &&
1051 SPEC_SCLS (sym->etype) != S_REGISTER &&
1052 SPEC_SCLS (sym->etype) != S_STACK &&
1053 SPEC_SCLS (sym->etype) != S_XSTACK &&
1054 SPEC_SCLS (sym->etype) != S_CONSTANT))
1057 werror (E_AUTO_ASSUMED, sym->name);
1058 SPEC_SCLS (sym->etype) = S_AUTO;
1061 /* automatic symbols cannot be given */
1062 /* an absolute address ignore it */
1064 SPEC_ABSA (sym->etype) &&
1065 (options.stackAuto || reentrant))
1067 werror (E_AUTO_ABSA, sym->name);
1068 SPEC_ABSA (sym->etype) = 0;
1071 /* arrays & pointers cannot be defined for bits */
1072 /* SBITS or SFRs or BIT */
1073 if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
1074 (SPEC_NOUN (sym->etype) == V_BIT ||
1075 SPEC_NOUN (sym->etype) == V_SBIT ||
1076 SPEC_SCLS (sym->etype) == S_SFR))
1077 werror (E_BIT_ARRAY, sym->name);
1079 /* if this is a bit|sbit then set length & start */
1080 if (SPEC_NOUN (sym->etype) == V_BIT ||
1081 SPEC_NOUN (sym->etype) == V_SBIT)
1083 SPEC_BLEN (sym->etype) = 1;
1084 SPEC_BSTR (sym->etype) = 0;
1087 /* variables declared in CODE space must have */
1088 /* initializers if not an extern */
1089 if (SPEC_SCLS (sym->etype) == S_CODE &&
1090 sym->ival == NULL &&
1092 port->mem.code_ro &&
1093 !IS_EXTERN (sym->etype) &&
1094 !funcInChain (sym->type))
1095 werror (E_CODE_NO_INIT, sym->name);
1097 /* if parameter or local variable then change */
1098 /* the storage class to reflect where the var will go */
1099 if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED)
1101 if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype)))
1103 SPEC_SCLS (sym->etype) = (options.useXstack ?
1104 S_XSTACK : S_STACK);
1108 /* hack-o-matic! I see no reason why the useXstack option should ever
1109 * control this allcoation, but the code was originally that way, and
1110 * changing it for non-390 ports breaks the compiler badly.
1112 bool useXdata = IS_DS390_PORT ? options.model : options.useXstack;
1113 SPEC_SCLS (sym->etype) = (useXdata ?
1119 /*------------------------------------------------------------------*/
1120 /* changePointer - change pointer to functions */
1121 /*------------------------------------------------------------------*/
1123 changePointer (symbol * sym)
1127 /* go thru the chain of declarations */
1128 /* if we find a pointer to a function */
1129 /* unconditionally change it to a ptr */
1131 for (p = sym->type; p; p = p->next)
1133 if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
1134 DCL_TYPE (p) = GPOINTER;
1135 if (IS_PTR (p) && IS_FUNC (p->next))
1136 DCL_TYPE (p) = CPOINTER;
1140 /*------------------------------------------------------------------*/
1141 /* checkDecl - does semantic validation of a declaration */
1142 /*------------------------------------------------------------------*/
1144 checkDecl (symbol * sym)
1147 checkSClass (sym); /* check the storage class */
1148 changePointer (sym); /* change pointers if required */
1150 /* if this is an array without any dimension
1151 then update the dimension from the initial value */
1152 if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type))
1153 DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival);
1158 /*------------------------------------------------------------------*/
1159 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1160 /*------------------------------------------------------------------*/
1162 copyLinkChain (sym_link * p)
1164 sym_link *head, *curr, *loop;
1167 head = loop = (curr ? newLink () : (void *) NULL);
1170 memcpy (loop, curr, sizeof (sym_link)); /* copy it */
1171 loop->next = (curr->next ? newLink () : (void *) NULL);
1180 /*------------------------------------------------------------------*/
1181 /* cleanUpBlock - cleansup the symbol table specified for all the */
1182 /* symbols in the given block */
1183 /*------------------------------------------------------------------*/
1185 cleanUpBlock (bucket ** table, int block)
1190 /* go thru the entire table */
1191 for (i = 0; i < 256; i++)
1193 for (chain = table[i]; chain; chain = chain->next)
1195 if (chain->block >= block)
1197 deleteSym (table, chain->sym, chain->name);
1203 /*------------------------------------------------------------------*/
1204 /* cleanUpLevel - cleansup the symbol table specified for all the */
1205 /* symbols in the given level */
1206 /*------------------------------------------------------------------*/
1208 cleanUpLevel (bucket ** table, int level)
1213 /* go thru the entire table */
1214 for (i = 0; i < 256; i++)
1216 for (chain = table[i]; chain; chain = chain->next)
1218 if (chain->level >= level)
1220 deleteSym (table, chain->sym, chain->name);
1226 /*------------------------------------------------------------------*/
1227 /* computeType - computes the resultant type from two types */
1228 /*------------------------------------------------------------------*/
1230 computeType (sym_link * type1, sym_link * type2)
1234 sym_link *etype1 = getSpec (type1);
1235 sym_link *etype2 = getSpec (type2);
1237 /* if one of them is a float then result is a float */
1238 /* here we assume that the types passed are okay */
1239 /* and can be cast to one another */
1240 /* which ever is greater in size */
1241 if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
1242 rType = newFloatLink ();
1244 /* if only one of them is a bit variable
1245 then the other one prevails */
1246 if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
1247 rType = copyLinkChain (type2);
1248 else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
1249 rType = copyLinkChain (type1);
1251 /* if one of them is a pointer then that
1254 rType = copyLinkChain (type1);
1255 else if (IS_PTR (type2))
1256 rType = copyLinkChain (type2);
1257 else if (getSize (type1) > getSize (type2))
1258 rType = copyLinkChain (type1);
1260 rType = copyLinkChain (type2);
1262 reType = getSpec (rType);
1264 /* if either of them unsigned then make this unsigned */
1265 if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType))
1266 SPEC_USIGN (reType) = 1;
1268 /* if result is a literal then make not so */
1269 if (IS_LITERAL (reType))
1270 SPEC_SCLS (reType) = S_REGISTER;
1275 /*------------------------------------------------------------------*/
1276 /* checkType - will do type check return 1 if match */
1277 /*------------------------------------------------------------------*/
1279 checkType (sym_link * dest, sym_link * src)
1290 /* if dest is a declarator then */
1295 if (DCL_TYPE (src) == DCL_TYPE (dest))
1296 return checkType (dest->next, src->next);
1297 else if (IS_PTR (src) && IS_PTR (dest))
1299 else if (IS_PTR (dest) && IS_ARRAY (src))
1301 else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
1302 return -1 * checkType (dest->next, src);
1306 else if (IS_PTR (dest) && IS_INTEGRAL (src))
1312 /* if one is a specifier and the other is not */
1313 if ((IS_SPEC (src) && !IS_SPEC (dest)) ||
1314 (IS_SPEC (dest) && !IS_SPEC (src)))
1317 /* if one of them is a void then ok */
1318 if (SPEC_NOUN (dest) == V_VOID &&
1319 SPEC_NOUN (src) != V_VOID)
1322 if (SPEC_NOUN (dest) != V_VOID &&
1323 SPEC_NOUN (src) == V_VOID)
1326 /* char === to short */
1327 if (SPEC_NOUN (dest) == V_CHAR &&
1328 SPEC_NOUN (src) == V_INT &&
1330 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1332 if (SPEC_NOUN (src) == V_CHAR &&
1333 SPEC_NOUN (dest) == V_INT &&
1335 return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
1337 /* if they are both bitfields then if the lengths
1338 and starts don't match */
1339 if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
1340 (SPEC_BLEN (dest) != SPEC_BLEN (src) ||
1341 SPEC_BSTR (dest) != SPEC_BSTR (src)))
1344 /* it is a specifier */
1345 if (SPEC_NOUN (dest) != SPEC_NOUN (src))
1347 if (SPEC_USIGN (dest) == SPEC_USIGN (src) &&
1348 IS_INTEGRAL (dest) && IS_INTEGRAL (src) &&
1349 getSize (dest) == getSize (src))
1351 else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src))
1356 else if (IS_STRUCT (dest))
1358 if (SPEC_STRUCT (dest) != SPEC_STRUCT (src))
1363 if (SPEC_LONG (dest) != SPEC_LONG (src))
1366 if (SPEC_SHORT (dest) != SPEC_SHORT (src))
1369 if (SPEC_USIGN (dest) != SPEC_USIGN (src))
1375 /*------------------------------------------------------------------*/
1376 /* inCalleeSaveList - return 1 if found in calle save list */
1377 /*------------------------------------------------------------------*/
1379 inCalleeSaveList (char *s)
1383 for (i = 0; options.calleeSaves[i]; i++)
1384 if (strcmp (options.calleeSaves[i], s) == 0)
1390 /*-----------------------------------------------------------------*/
1391 /* aggregateArgToPointer: change an agggregate type function */
1392 /* argument to a pointer to that type. */
1393 /*-----------------------------------------------------------------*/
1395 aggregateArgToPointer (value * val)
1397 if (IS_AGGREGATE (val->type))
1399 /* if this is a structure */
1400 /* then we need to add a new link */
1401 if (IS_STRUCT (val->type))
1403 /* first lets add DECLARATOR type */
1404 sym_link *p = val->type;
1406 werror (W_STRUCT_AS_ARG, val->name);
1407 val->type = newLink ();
1408 val->type->next = p;
1411 /* change to a pointer depending on the */
1412 /* storage class specified */
1413 switch (SPEC_SCLS (val->etype))
1416 DCL_TYPE (val->type) = IPOINTER;
1419 DCL_TYPE (val->type) = PPOINTER;
1424 /* The AUTO and REGISTER classes should probably
1425 * also become generic pointers, but I haven't yet
1426 * devised a test case for that.
1428 DCL_TYPE (val->type) = GPOINTER;
1435 DCL_TYPE (val->type) = POINTER;
1438 DCL_TYPE (val->type) = CPOINTER;
1441 DCL_TYPE (val->type) = FPOINTER;
1444 DCL_TYPE (val->type) = EEPPOINTER;
1447 DCL_TYPE (val->type) = GPOINTER;
1450 /* is there is a symbol associated then */
1451 /* change the type of the symbol as well */
1454 val->sym->type = copyLinkChain (val->type);
1455 val->sym->etype = getSpec (val->sym->type);
1459 /*------------------------------------------------------------------*/
1460 /* checkFunction - does all kinds of check on a function */
1461 /*------------------------------------------------------------------*/
1463 checkFunction (symbol * sym)
1466 value *exargs, *acargs;
1469 /* if not type then some kind of error */
1473 /* if the function has no type then make it return int */
1474 if (!sym->type->next)
1475 sym->type->next = sym->etype = newIntLink ();
1477 /* function cannot return aggregate */
1478 if (IS_AGGREGATE (sym->type->next))
1480 werror (E_FUNC_AGGR, sym->name);
1484 /* function cannot return bit */
1485 if (IS_BITVAR (sym->type->next))
1487 werror (E_FUNC_BIT, sym->name);
1491 /* check if this function is defined as calleeSaves
1492 then mark it as such */
1493 sym->calleeSave = inCalleeSaveList (sym->name);
1495 /* if interrupt service routine */
1496 /* then it cannot have arguments */
1497 if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type))
1499 werror (E_INT_ARGS, sym->name);
1503 if (!(csym = findSym (SymbolTab, sym, sym->name)))
1504 return 1; /* not defined nothing more to check */
1506 /* check if body already present */
1507 if (csym && csym->fbody)
1509 werror (E_FUNC_BODY, sym->name);
1513 /* check the return value type */
1514 if (checkType (csym->type, sym->type) <= 0)
1516 werror (E_PREV_DEF_CONFLICT, csym->name, "type");
1517 werror (E_CONTINUE, "previous defintion type ");
1518 printTypeChain (csym->type, stderr);
1519 fprintf (stderr, "\n");
1520 werror (E_CONTINUE, "current definition type ");
1521 printTypeChain (sym->type, stderr);
1522 fprintf (stderr, "\n");
1526 if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
1528 werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
1532 if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
1534 werror (E_PREV_DEF_CONFLICT, csym->name, "using");
1538 /* compare expected agrs with actual args */
1539 exargs = csym->args;
1542 /* for all the expected args do */
1545 exargs = exargs->next, acargs = acargs->next, argCnt++)
1548 /* If the actual argument is an array, any prototype
1549 * will have modified it to a pointer. Duplicate that
1552 if (IS_AGGREGATE (acargs->type))
1554 checkValue = copyValue (acargs);
1555 aggregateArgToPointer (checkValue);
1559 checkValue = acargs;
1562 if (checkType (exargs->type, checkValue->type) <= 0)
1564 werror (E_ARG_TYPE, argCnt);
1569 /* if one them ended we have a problem */
1570 if ((exargs && !acargs && !IS_VOID (exargs->type)) ||
1571 (!exargs && acargs && !IS_VOID (acargs->type)))
1572 werror (E_ARG_COUNT);
1574 /* replace with this defition */
1575 sym->cdef = csym->cdef;
1576 deleteSym (SymbolTab, csym, csym->name);
1577 addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
1578 if (IS_EXTERN (csym->etype) && !
1579 IS_EXTERN (sym->etype))
1581 addSet (&publics, sym);
1586 /*-----------------------------------------------------------------*/
1587 /* processFuncArgs - does some processing with function args */
1588 /*-----------------------------------------------------------------*/
1590 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 not inhibited by command line option or #pragma */
1624 if (!func->hasVargs &&
1625 !options.noregparms &&
1626 !IS_RENT (func->etype) &&
1627 (*port->reg_parm) (val->type))
1629 SPEC_REGPARM (val->etype) = 1;
1632 if (IS_AGGREGATE (val->type))
1634 aggregateArgToPointer (val);
1640 /* if this function is reentrant or */
1641 /* automatics r 2b stacked then nothing */
1642 if (IS_RENT (func->etype) || options.stackAuto)
1650 /* if a symbolname is not given */
1651 /* synthesize a variable name */
1655 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1656 val->sym = newSymbol (val->name, 1);
1657 SPEC_OCLS (val->etype) = port->mem.default_local_map;
1658 val->sym->type = copyLinkChain (val->type);
1659 val->sym->etype = getSpec (val->sym->type);
1660 val->sym->_isparm = 1;
1661 strcpy (val->sym->rname, val->name);
1662 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1663 SPEC_STAT (func->etype);
1664 addSymChain (val->sym);
1667 else /* symbol name given create synth name */
1670 sprintf (val->name, "_%s_PARM_%d", func->name, pNum++);
1671 strcpy (val->sym->rname, val->name);
1672 val->sym->_isparm = 1;
1673 SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) =
1674 (options.model != MODEL_SMALL ? xdata : data);
1675 SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) =
1676 SPEC_STAT (func->etype);
1682 /*-----------------------------------------------------------------*/
1683 /* isSymbolEqual - compares two symbols return 1 if they match */
1684 /*-----------------------------------------------------------------*/
1686 isSymbolEqual (symbol * dest, symbol * src)
1688 /* if pointers match then equal */
1692 /* if one of them is null then don't match */
1696 /* if both of them have rname match on rname */
1697 if (dest->rname[0] && src->rname[0])
1698 return (!strcmp (dest->rname, src->rname));
1700 /* otherwise match on name */
1701 return (!strcmp (dest->name, src->name));
1704 void PT(sym_link *type)
1706 printTypeChain(type,0);
1708 /*-----------------------------------------------------------------*/
1709 /* printTypeChain - prints the type chain in human readable form */
1710 /*-----------------------------------------------------------------*/
1712 printTypeChain (sym_link * type, FILE * of)
1726 switch (DCL_TYPE (type))
1729 fprintf (of, "function ");
1732 fprintf (of, "_generic * ");
1733 if (DCL_PTR_CONST (type))
1734 fprintf (of, "const ");
1737 fprintf (of, "_code * ");
1738 if (DCL_PTR_CONST (type))
1739 fprintf (of, "const ");
1742 fprintf (of, "_far * ");
1743 if (DCL_PTR_CONST (type))
1744 fprintf (of, "const ");
1747 fprintf (of, "_eeprom * ");
1748 if (DCL_PTR_CONST (type))
1749 fprintf (of, "const ");
1753 fprintf (of, "_near * ");
1754 if (DCL_PTR_CONST (type))
1755 fprintf (of, "const ");
1758 fprintf (of, "_idata *");
1759 if (DCL_PTR_CONST (type))
1760 fprintf (of, "const ");
1763 fprintf (of, "_pdata *");
1764 if (DCL_PTR_CONST (type))
1765 fprintf (of, "const ");
1768 fprintf (of, " _unkown *");
1769 if (DCL_PTR_CONST (type))
1770 fprintf (of, "const ");
1774 fprintf (of, "array of ");
1780 if (SPEC_VOLATILE (type))
1781 fprintf (of, "volatile ");
1782 if (SPEC_USIGN (type))
1783 fprintf (of, "unsigned ");
1784 if (SPEC_CONST (type))
1785 fprintf (of, "const ");
1787 switch (SPEC_NOUN (type))
1791 fprintf (of, "long ");
1792 else if (IS_SHORT (type))
1793 fprintf (of, "short ");
1795 fprintf (of, "int ");
1799 fprintf (of, "char ");
1803 fprintf (of, "void ");
1807 fprintf (of, "float ");
1811 fprintf (of, "struct %s", SPEC_STRUCT (type)->tag);
1815 fprintf (of, "sbit ");
1819 fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
1832 /*-----------------------------------------------------------------*/
1833 /* cdbTypeInfo - print the type information for debugger */
1834 /*-----------------------------------------------------------------*/
1836 cdbTypeInfo (sym_link * type, FILE * of)
1838 fprintf (of, "{%d}", getSize (type));
1843 switch (DCL_TYPE (type))
1846 fprintf (of, "DF,");
1849 fprintf (of, "DG,");
1852 fprintf (of, "DC,");
1855 fprintf (of, "DX,");
1858 fprintf (of, "DD,");
1861 fprintf (of, "DI,");
1864 fprintf (of, "DP,");
1867 fprintf (of, "DA,");
1870 fprintf (of, "DA%d,", DCL_ELEM (type));
1878 switch (SPEC_NOUN (type))
1883 else if (IS_SHORT (type))
1902 fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
1910 fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
1917 if (SPEC_USIGN (type))
1925 /*-----------------------------------------------------------------*/
1926 /* cdbSymbol - prints a symbol & its type information for debugger */
1927 /*-----------------------------------------------------------------*/
1929 cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
1941 fprintf (of, "S:"); /* symbol record */
1942 /* if this is not a structure symbol then
1943 we need to figure out the scope information */
1949 if (IS_STATIC (sym->etype))
1950 fprintf (of, "F%s$", moduleName); /* scope is file */
1952 fprintf (of, "G$"); /* scope is global */
1955 /* symbol is local */
1956 fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
1959 fprintf (of, "S$"); /* scope is structure */
1961 /* print the name, & mangled name */
1962 fprintf (of, "%s$%d$%d(", sym->name,
1963 sym->level, sym->block);
1965 cdbTypeInfo (sym->type, of);
1968 /* print the address space */
1969 map = SPEC_OCLS (sym->etype);
1970 fprintf (of, "%c,%d,%d",
1971 (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
1973 /* if assigned to registers then output register names */
1974 /* if this is a function then print
1975 if is it an interrupt routine & interrupt number
1976 and the register bank it is using */
1978 fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype),
1979 SPEC_INTN (sym->etype), SPEC_BANK (sym->etype));
1980 /* alternate location to find this symbol @ : eg registers
1987 /*-----------------------------------------------------------------*/
1988 /* cdbStruct - print a structure for debugger */
1989 /*-----------------------------------------------------------------*/
1991 cdbStruct (structdef * sdef, int block, FILE * of,
1992 int inStruct, char *tag)
1997 /* if block # then must have function scope */
1998 fprintf (of, "F%s$", moduleName);
1999 fprintf (of, "%s[", (tag ? tag : sdef->tag));
2000 for (sym = sdef->fields; sym; sym = sym->next)
2002 fprintf (of, "({%d}", sym->offset);
2003 cdbSymbol (sym, of, TRUE, FALSE);
2011 /*------------------------------------------------------------------*/
2012 /* cdbStructBlock - calls struct printing for a blcks */
2013 /*------------------------------------------------------------------*/
2015 cdbStructBlock (int block, FILE * of)
2018 bucket **table = StructTab;
2022 /* go thru the entire table */
2023 for (i = 0; i < 256; i++)
2025 for (chain = table[i]; chain; chain = chain->next)
2027 if (chain->block >= block)
2029 cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
2035 /*-----------------------------------------------------------------*/
2036 /* powof2 - returns power of two for the number if number is pow 2 */
2037 /*-----------------------------------------------------------------*/
2039 powof2 (unsigned long num)
2052 if (n1s > 1 || nshifts == 0)
2068 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
2069 symbol *__muldiv[3][3][2];
2070 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
2071 sym_link *__multypes[3][2];
2072 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
2073 symbol *__conv[2][3][2];
2075 sym_link *floatType;
2078 _makeRegParam (symbol * sym)
2082 val = sym->args; /* loop thru all the arguments */
2084 /* reset regparm for the port */
2085 (*port->reset_regparms) ();
2088 SPEC_REGPARM (val->etype) = 1;
2089 sym->argStack -= getSize (val->type);
2094 /*-----------------------------------------------------------------*/
2095 /* initCSupport - create functions for C support routines */
2096 /*-----------------------------------------------------------------*/
2100 const char *smuldivmod[] =
2104 const char *sbwd[] =
2106 "char", "int", "long"
2113 int bwd, su, muldivmod, tofrom;
2115 floatType = newFloatLink ();
2117 for (bwd = 0; bwd < 3; bwd++)
2134 __multypes[bwd][0] = l;
2135 __multypes[bwd][1] = copyLinkChain (l);
2136 SPEC_USIGN (__multypes[bwd][1]) = 1;
2139 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
2140 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
2141 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
2142 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
2143 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
2144 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
2145 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
2146 __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
2147 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
2148 __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
2150 for (tofrom = 0; tofrom < 2; tofrom++)
2152 for (bwd = 0; bwd < 3; bwd++)
2154 for (su = 0; su < 2; su++)
2158 sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
2159 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
2163 sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
2164 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2170 for (muldivmod = 0; muldivmod < 3; muldivmod++)
2172 for (bwd = 0; bwd < 3; bwd++)
2174 for (su = 0; su < 2; su++)
2176 sprintf (buffer, "_%s%s%s",
2177 smuldivmod[muldivmod],
2180 __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2181 SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
2182 if (bwd < port->muldiv.force_reg_param_below)
2183 _makeRegParam (__muldiv[muldivmod][bwd][su]);