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 /*------------------------------------------------------------------*/
40 for ( i = 0 ; i < 256 ; i++ )
41 SymbolTab[i] = StructTab[i] = (void *) NULL ;
45 /*-----------------------------------------------------------------*/
46 /* newBucket - allocates & returns a new bucket */
47 /*-----------------------------------------------------------------*/
52 bp = Safe_calloc(1,sizeof(bucket));
57 /*-----------------------------------------------------------------*/
58 /* hashKey - computes the hashkey given a symbol name */
59 /*-----------------------------------------------------------------*/
60 int hashKey (const char *s)
62 unsigned long key = 0;
69 /*-----------------------------------------------------------------*/
70 /* addSym - adds a symbol to the hash Table */
71 /*-----------------------------------------------------------------*/
72 void addSym ( bucket **stab ,
78 int i ; /* index into the hash Table */
79 bucket *bp ; /* temp bucket * */
81 /* the symbols are always added at the head of the list */
83 /* get a free entry */
84 bp = Safe_calloc(1,sizeof(bucket));
86 bp->sym = sym ; /* update the symbol pointer */
87 bp->level = level; /* update the nest level */
89 strcpy(bp->name,sname); /* copy the name into place */
91 /* if this is the first entry */
92 if (stab[i] == NULL) {
93 bp->prev = bp->next = (void *) NULL ; /* point to nothing */
96 /* not first entry then add @ head of list */
105 /*-----------------------------------------------------------------*/
106 /* deleteSym - deletes a symbol from the hash Table entry */
107 /*-----------------------------------------------------------------*/
108 void deleteSym ( bucket **stab, void *sym, char *sname)
116 /* find the symbol */
118 if (bp->sym == sym) /* found it then break out */
119 break ; /* of the loop */
123 if (!bp) /* did not find it */
125 /* if this is the first one in the chain */
128 if ( stab[i] ) /* if chain ! empty */
129 stab[i]->prev = (void *) NULL ;
131 /* middle || end of chain */
133 if ( bp->next ) /* if not end of chain */
134 bp->next->prev = bp->prev ;
136 bp->prev->next = bp->next ;
141 /*-----------------------------------------------------------------*/
142 /* findSym - finds a symbol in a table */
143 /*-----------------------------------------------------------------*/
144 void *findSym ( bucket **stab, void *sym, const char *sname)
148 bp = stab[hashKey(sname)] ;
151 if ( bp->sym == sym || strcmp (bp->name,sname) == 0 )
156 return ( bp ? bp->sym : (void *) NULL ) ;
159 /*-----------------------------------------------------------------*/
160 /* findSymWithLevel - finds a symbol with a name & level */
161 /*-----------------------------------------------------------------*/
162 void *findSymWithLevel ( bucket **stab, symbol *sym)
166 bp = stab[hashKey(sym->name)];
169 ** do the search from the head of the list since the
170 ** elements are added at the head it is ensured that
171 ** we will find the deeper definitions before we find
172 ** the global ones. we need to check for symbols with
173 ** level <= to the level given, if levels match then block
174 ** numbers need to match as well
178 if ( strcmp(bp->name,sym->name) == 0 && bp->level <= sym->level) {
179 /* if this is parameter then nothing else need to be checked */
180 if (((symbol *)(bp->sym))->_isparm)
182 /* if levels match then block numbers hsould also match */
183 if (bp->level && bp->level == sym->level && bp->block == sym->block )
185 /* if levels don't match then we are okay */
186 if (bp->level && bp->level != sym->level)
188 /* if this is a global variable then we are ok too */
196 return (void *) NULL ;
199 /*-----------------------------------------------------------------*/
200 /* findSymWithBlock - finds a symbol with name in with a block */
201 /*-----------------------------------------------------------------*/
202 void *findSymWithBlock ( bucket **stab, symbol *sym, int block)
206 bp = stab[hashKey(sym->name)] ;
209 if ( strcmp (bp->name,sym->name) == 0 &&
215 return ( bp ? bp->sym : (void *) NULL ) ;
218 /*------------------------------------------------------------------*/
219 /* newSymbol () - returns a new pointer to a symbol */
220 /*------------------------------------------------------------------*/
221 symbol *newSymbol (char *name, int scope )
225 sym = Safe_calloc(1,sizeof(symbol));
227 strcpy(sym->name,name); /* copy the name */
228 sym->level = scope ; /* set the level */
229 sym->block = currBlockno ;
230 sym->lineDef = yylineno ; /* set the line number */
234 /*------------------------------------------------------------------*/
235 /* newLink - creates a new link (declarator,specifier) */
236 /*------------------------------------------------------------------*/
241 p = Safe_calloc(1,sizeof(sym_link));
246 /*------------------------------------------------------------------*/
247 /* newStruct - creats a new structdef from the free list */
248 /*------------------------------------------------------------------*/
249 structdef *newStruct ( char *tag )
253 s = Safe_calloc(1,sizeof(structdef));
255 strcpy(s->tag,tag) ; /* copy the tag */
259 /*------------------------------------------------------------------*/
260 /* pointerTypes - do the computation for the pointer types */
261 /*------------------------------------------------------------------*/
262 void pointerTypes (sym_link *ptr, sym_link *type)
267 /* find the first pointer type */
268 while (ptr && !IS_PTR(ptr))
271 /* could not find it */
272 if (!ptr || IS_SPEC(ptr) ||
273 DCL_TYPE(ptr) != UPOINTER)
276 /* change the pointer type depending on the
277 storage class of the type */
279 DCL_PTR_CONST(ptr) = SPEC_CONST(type);
280 DCL_PTR_VOLATILE(ptr) = SPEC_VOLATILE(type);
281 switch (SPEC_SCLS(type)) {
283 DCL_TYPE(ptr) = FPOINTER;
286 DCL_TYPE(ptr) = IPOINTER ;
289 DCL_TYPE(ptr) = PPOINTER ;
292 DCL_TYPE(ptr) = POINTER ;
295 DCL_PTR_CONST(ptr) = port->mem.code_ro;
296 DCL_TYPE(ptr) = CPOINTER ;
299 DCL_TYPE(ptr) = EEPPOINTER;
302 DCL_TYPE(ptr) = GPOINTER;
305 /* the storage class of type ends here */
308 SPEC_VOLATILE(type) = 0;
311 /* now change all the remaining unknown pointers
312 to generic pointers */
314 if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER)
315 DCL_TYPE(ptr) = GPOINTER;
319 /* same for the type although it is highly unlikely that
320 type will have a pointer */
322 if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER)
323 DCL_TYPE(type) = GPOINTER;
329 /*------------------------------------------------------------------*/
330 /* addDecl - adds a declarator @ the end of a chain */
331 /*------------------------------------------------------------------*/
332 void addDecl ( symbol *sym, int type , sym_link *p )
338 /* if we are passed a link then set head & tail */
345 head = tail = newLink() ;
346 DCL_TYPE(head) = type ;
349 /* if this is the first entry */
355 if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) {
356 sym->etype = mergeSpec(sym->etype,head);
359 if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) {
361 while (t->next != sym->etype) t = t->next ;
363 tail->next = sym->etype;
365 sym->etype->next = head;
371 /* if the type is a unknown pointer and has
372 a tspec then take the storage class const & volatile
373 attribute from the tspec & make it those of this
377 DCL_TYPE(p) == UPOINTER &&
379 if (!IS_SPEC(sym->etype)) {
380 sym->etype = sym->etype->next = newLink();
381 sym->etype->class = SPECIFIER;
383 SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p));
384 SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p));
385 SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p));
391 /*------------------------------------------------------------------*/
392 /* mergeSpec - merges two specifiers and returns the new one */
393 /*------------------------------------------------------------------*/
394 sym_link *mergeSpec ( sym_link *dest, sym_link *src )
396 /* if noun different then src overrides */
397 if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest))
398 SPEC_NOUN(dest) = SPEC_NOUN(src) ;
400 if (! SPEC_SCLS(dest)) /* if destination has no storage class */
401 SPEC_SCLS(dest) = SPEC_SCLS(src) ;
403 /* copy all the specifications */
404 SPEC_LONG(dest) |= SPEC_LONG(src);
405 SPEC_SHORT(dest) |= SPEC_SHORT(src);
406 SPEC_USIGN(dest) |= SPEC_USIGN(src);
407 SPEC_STAT(dest) |= SPEC_STAT(src);
408 SPEC_EXTR(dest) |= SPEC_EXTR(src);
409 SPEC_ABSA(dest) |= SPEC_ABSA(src);
410 SPEC_RENT(dest) |= SPEC_RENT(src);
411 SPEC_INTN(dest) |= SPEC_INTN(src);
412 SPEC_BANK(dest) |= SPEC_BANK(src);
413 SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src);
414 SPEC_CRTCL(dest) |= SPEC_CRTCL(src);
415 SPEC_ADDR(dest) |= SPEC_ADDR(src);
416 SPEC_OCLS(dest) = SPEC_OCLS(src);
417 SPEC_BLEN(dest) |= SPEC_BLEN(src);
418 SPEC_BSTR(dest) |= SPEC_BSTR(src);
419 SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src);
420 SPEC_NONBANKED(dest) |= SPEC_NONBANKED(src);
422 if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL )
423 SPEC_STRUCT(dest) = SPEC_STRUCT(src);
428 /*------------------------------------------------------------------*/
429 /* cloneSpec - copies the entire spec and returns a new spec */
430 /*------------------------------------------------------------------*/
431 sym_link *cloneSpec ( sym_link *src )
435 /* go thru chain till we find the specifier */
436 while ( src && src->class != SPECIFIER )
440 memcpy (spec,src,sizeof(sym_link));
444 /*------------------------------------------------------------------*/
445 /* genSymName - generates and returns a name used for anonymous vars*/
446 /*------------------------------------------------------------------*/
447 char *genSymName ( int level )
449 static int gCount = 0 ;
450 static char gname[SDCC_NAME_MAX+1] ;
452 sprintf (gname,"__%04d%04d",level,gCount++);
456 /*------------------------------------------------------------------*/
457 /* getSpec - returns the specifier part from a declaration chain */
458 /*------------------------------------------------------------------*/
459 sym_link *getSpec ( sym_link *p )
464 while ( p && ! (IS_SPEC(p)))
470 /*------------------------------------------------------------------*/
471 /* newCharLink() - creates an int type */
472 /*------------------------------------------------------------------*/
473 sym_link *newCharLink()
478 p->class = SPECIFIER ;
479 SPEC_NOUN(p) = V_CHAR ;
484 /*------------------------------------------------------------------*/
485 /* newFloatLink - a new Float type */
486 /*------------------------------------------------------------------*/
487 sym_link *newFloatLink()
492 p->class = SPECIFIER ;
493 SPEC_NOUN(p) = V_FLOAT ;
498 /*------------------------------------------------------------------*/
499 /* newLongLink() - new long type */
500 /*------------------------------------------------------------------*/
501 sym_link *newLongLink()
506 p->class = SPECIFIER ;
507 SPEC_NOUN(p) = V_INT ;
513 /*------------------------------------------------------------------*/
514 /* newIntLink() - creates an int type */
515 /*------------------------------------------------------------------*/
516 sym_link *newIntLink()
521 p->class = SPECIFIER ;
522 SPEC_NOUN(p) = V_INT ;
527 /*------------------------------------------------------------------*/
528 /* getSize - returns size of a type chain in bits */
529 /*------------------------------------------------------------------*/
530 unsigned int getSize ( sym_link *p )
532 /* if nothing return 0 */
535 if ( IS_SPEC(p) ) { /* if this is the specifier then */
536 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
538 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
546 return SPEC_STRUCT(p)->size ;
552 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
558 /* this is a specifier */
559 switch (DCL_TYPE(p)) {
563 return DCL_ELEM(p) * getSize (p->next) ;
580 /*------------------------------------------------------------------*/
581 /* bitsForType - returns # of bits required to store this type */
582 /*------------------------------------------------------------------*/
583 unsigned int bitsForType ( sym_link *p )
585 /* if nothing return 0 */
589 if ( IS_SPEC(p) ) { /* if this is the specifier then */
591 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
593 return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
601 return SPEC_STRUCT(p)->size*8 ;
613 /* this is a specifier */
614 switch (DCL_TYPE(p)) {
618 return DCL_ELEM(p) * getSize (p->next) *8 ;
622 return ( PTRSIZE * 8) ;
626 return ( FPTRSIZE * 8);
628 return ( GPTRSIZE * 8);
635 /*------------------------------------------------------------------*/
636 /* copySymbolChain - copies a symbol chain */
637 /*------------------------------------------------------------------*/
638 symbol *copySymbolChain (symbol *src)
645 dest = copySymbol(src);
646 dest->next = copySymbolChain(src->next);
650 /*------------------------------------------------------------------*/
651 /* copySymbol - makes a copy of a symbol */
652 /*------------------------------------------------------------------*/
653 symbol *copySymbol (symbol *src)
660 dest = newSymbol( src->name, src->level );
661 memcpy(dest,src,sizeof(symbol));
662 dest->level = src->level ;
663 dest->block = src->block ;
664 dest->ival = copyIlist(src->ival);
665 dest->type = copyLinkChain(src->type);
666 dest->etype= getSpec(dest->type);
668 dest->args = copyValueChain (src->args);
669 dest->key = src->key;
670 dest->calleeSave = src->calleeSave;
671 dest->allocreq = src->allocreq;
675 /*------------------------------------------------------------------*/
676 /* reverseSyms - reverses the links for a symbol chain */
677 /*------------------------------------------------------------------*/
678 symbol *reverseSyms ( symbol *sym)
680 symbol *prev , *curr, *next ;
695 sym->next = (void *) NULL ;
699 /*------------------------------------------------------------------*/
700 /* reverseLink - reverses the links for a type chain */
701 /*------------------------------------------------------------------*/
702 sym_link *reverseLink ( sym_link *type)
704 sym_link *prev , *curr, *next ;
719 type->next = (void *) NULL ;
723 /*------------------------------------------------------------------*/
724 /* addSymChain - adds a symbol chain to the symboltable */
725 /*------------------------------------------------------------------*/
726 void addSymChain ( symbol *symHead )
728 symbol *sym = symHead ;
729 symbol *csym = NULL ;
731 for (;sym != NULL ; sym = sym->next ) {
733 /* if already exists in the symbol table then check if
734 the previous was an extern definition if yes then
735 then check if the type match, if the types match then
736 delete the current entry and add the new entry */
737 if ((csym = findSymWithLevel (SymbolTab,sym)) &&
738 csym->level == sym->level) {
740 /* previous definition extern ? */
741 if ( IS_EXTERN(csym->etype) ) {
742 /* do types match ? */
743 if (checkType ( csym->type,sym->type) != 1)
745 werror (E_DUPLICATE,csym->name);
747 /* delete current entry */
748 deleteSym (SymbolTab, csym, csym->name );
750 addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
751 } else /* not extern */
752 werror(E_DUPLICATE,sym->name) ;
756 /* check if previously defined */
757 if (csym && csym->level == sym->level ) {
758 /* if the previous one was declared as extern */
759 /* then check the type with the current one */
760 if ( IS_EXTERN(csym->etype) ) {
761 if ( checkType (csym->type, sym->type ) <= 0 )
762 werror (W_EXTERN_MISMATCH,csym->name);
766 addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
771 /*------------------------------------------------------------------*/
772 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
773 /*------------------------------------------------------------------*/
774 int funcInChain (sym_link *lnk)
784 /*------------------------------------------------------------------*/
785 /* structElemType - returns the type info of a sturct member */
786 /*------------------------------------------------------------------*/
787 sym_link *structElemType (sym_link *stype, value *id ,value **argsp)
789 symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
790 sym_link *type, *etype;
791 sym_link *petype = getSpec(stype);
793 if ( ! fields || ! id)
796 /* look for the id */
798 if (strcmp(fields->rname,id->name) == 0) {
800 *argsp = fields->args;
802 type = copyLinkChain (fields->type) ;
804 SPEC_SCLS(etype) = (SPEC_SCLS(petype) == S_REGISTER ?
805 SPEC_SCLS(etype) : SPEC_SCLS(petype));
808 fields = fields->next ;
810 werror(E_NOT_MEMBER,id->name);
815 /*------------------------------------------------------------------*/
816 /* getStructElement - returns element of a tructure definition */
817 /*------------------------------------------------------------------*/
818 symbol *getStructElement ( structdef *sdef, symbol *sym)
822 for ( field = sdef->fields ; field ; field = field->next )
823 if ( strcmp(field->name,sym->name) == 0)
826 werror(E_NOT_MEMBER,sym->name);
828 return sdef->fields ;
831 /*------------------------------------------------------------------*/
832 /* compStructSize - computes the size of a structure */
833 /*------------------------------------------------------------------*/
834 int compStructSize (int su, structdef *sdef )
836 int sum = 0 , usum =0;
840 /* for the identifiers */
841 loop = sdef->fields ;
844 /* create the internal name for this variable */
845 sprintf (loop->rname,"_%s",loop->name);
846 loop->offset = ( su == UNION ? sum = 0 : sum ) ;
847 SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
849 /* if this is a bit field */
852 /* change it to a unsigned bit */
853 SPEC_NOUN(loop->etype) = V_BIT ;
854 SPEC_USIGN(loop->etype) = 1 ;
855 /* check if this fit into the remaining */
856 /* bits of this byte else align it to the */
857 /* next byte boundary */
858 if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset)) {
859 SPEC_BSTR(loop->etype) = bitOffset ;
860 if ((bitOffset += (loop->bitVar % 8)) == 8) sum++;
862 else /* does not fit */
865 SPEC_BSTR(loop->etype) = bitOffset ;
866 sum += (loop->bitVar / 8) ;
867 bitOffset += (loop->bitVar % 8);
869 /* if this is the last field then pad */
870 if (!loop->next && bitOffset && bitOffset != 8) {
877 sum += getSize (loop->type) ;
880 /* if function then do the arguments for it */
881 if (funcInChain(loop->type)) {
882 processFuncArgs (loop, 1);
887 /* if this is not a bitfield but the */
888 /* previous one was and did not take */
889 /* the whole byte then pad the rest */
890 if ((loop && !loop->bitVar) && bitOffset) {
895 /* if union then size = sizeof larget field */
897 usum = max(usum,sum);
901 return (su == UNION ? usum : sum);
904 /*------------------------------------------------------------------*/
905 /* checkSClass - check the storage class specification */
906 /*------------------------------------------------------------------*/
907 static void checkSClass ( symbol *sym )
909 /* type is literal can happen foe enums change
911 if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
912 SPEC_SCLS(sym->etype) = S_AUTO;
914 /* if sfr or sbit then must also be */
915 /* volatile the initial value will be xlated */
916 /* to an absolute address */
917 if (SPEC_SCLS(sym->etype) == S_SBIT ||
918 SPEC_SCLS(sym->etype) == S_SFR ) {
919 SPEC_VOLATILE(sym->etype) = 1;
920 /* if initial value given */
922 SPEC_ABSA(sym->etype) = 1;
923 SPEC_ADDR(sym->etype) =
924 (int) list2int(sym->ival);
929 /* if absolute address given then it mark it as
931 if (IS_ABSOLUTE(sym->etype))
932 SPEC_VOLATILE(sym->etype) = 1;
934 /* global variables declared const put into code */
935 if (sym->level == 0 &&
936 SPEC_SCLS(sym->etype) == S_CONSTANT) {
937 SPEC_SCLS(sym->etype) = S_CODE ;
938 SPEC_CONST(sym->etype) = 1;
941 /* global variable in code space is a constant */
942 if (sym->level == 0 &&
943 SPEC_SCLS(sym->etype) == S_CODE &&
945 SPEC_CONST(sym->etype) = 1;
948 /* if bit variable then no storage class can be */
949 /* specified since bit is already a storage */
950 if ( IS_BITVAR(sym->etype) &&
951 ( SPEC_SCLS(sym->etype) != S_FIXED &&
952 SPEC_SCLS(sym->etype) != S_SBIT &&
953 SPEC_SCLS(sym->etype) != S_BIT )
955 werror (E_BITVAR_STORAGE,sym->name);
956 SPEC_SCLS(sym->etype) = S_FIXED ;
959 /* extern variables cannot be initialized */
960 if (IS_EXTERN(sym->etype) && sym->ival) {
961 werror(E_EXTERN_INIT,sym->name);
965 /* if this is an automatic symbol then */
966 /* storage class will be ignored and */
967 /* symbol will be allocated on stack/ */
968 /* data depending on flag */
970 (options.stackAuto || reentrant ) &&
971 ( SPEC_SCLS(sym->etype) != S_AUTO &&
972 SPEC_SCLS(sym->etype) != S_FIXED &&
973 SPEC_SCLS(sym->etype) != S_REGISTER &&
974 SPEC_SCLS(sym->etype) != S_STACK &&
975 SPEC_SCLS(sym->etype) != S_XSTACK &&
976 SPEC_SCLS(sym->etype) != S_CONSTANT )) {
978 werror(E_AUTO_ASSUMED,sym->name) ;
979 SPEC_SCLS(sym->etype) = S_AUTO ;
982 /* automatic symbols cannot be given */
983 /* an absolute address ignore it */
985 SPEC_ABSA(sym->etype) &&
986 (options.stackAuto || reentrant) ) {
987 werror(E_AUTO_ABSA,sym->name);
988 SPEC_ABSA(sym->etype) = 0 ;
991 /* arrays & pointers cannot be defined for bits */
992 /* SBITS or SFRs or BIT */
993 if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
994 ( SPEC_NOUN(sym->etype) == V_BIT ||
995 SPEC_NOUN(sym->etype) == V_SBIT ||
996 SPEC_SCLS(sym->etype) == S_SFR ))
997 werror(E_BIT_ARRAY,sym->name);
999 /* if this is a bit|sbit then set length & start */
1000 if (SPEC_NOUN(sym->etype) == V_BIT ||
1001 SPEC_NOUN(sym->etype) == V_SBIT ) {
1002 SPEC_BLEN(sym->etype) = 1 ;
1003 SPEC_BSTR(sym->etype) = 0 ;
1006 /* variables declared in CODE space must have */
1007 /* initializers if not an extern */
1008 if (SPEC_SCLS(sym->etype) == S_CODE &&
1009 sym->ival == NULL &&
1011 port->mem.code_ro &&
1012 !IS_EXTERN(sym->etype) &&
1013 !funcInChain(sym->type))
1014 werror(E_CODE_NO_INIT,sym->name);
1016 /* if parameter or local variable then change */
1017 /* the storage class to reflect where the var will go */
1018 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1019 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1021 SPEC_SCLS(sym->etype) = (options.useXstack ?
1022 S_XSTACK : S_STACK ) ;
1026 /* hack-o-matic! I see no reason why the useXstack option should ever
1027 * control this allcoation, but the code was originally that way, and
1028 * changing it for non-390 ports breaks the compiler badly.
1030 bool useXdata = IS_DS390_PORT ? options.model : options.useXstack;
1031 SPEC_SCLS(sym->etype) = (useXdata ?
1032 S_XDATA : S_FIXED ) ;
1037 /*------------------------------------------------------------------*/
1038 /* changePointer - change pointer to functions */
1039 /*------------------------------------------------------------------*/
1040 void changePointer (symbol *sym)
1044 /* go thru the chain of declarations */
1045 /* if we find a pointer to a function */
1046 /* unconditionally change it to a ptr */
1048 for ( p = sym->type ; p ; p = p->next) {
1049 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1050 DCL_TYPE(p) = GPOINTER ;
1051 if ( IS_PTR(p) && IS_FUNC(p->next))
1052 DCL_TYPE(p) = CPOINTER ;
1056 /*------------------------------------------------------------------*/
1057 /* checkDecl - does semantic validation of a declaration */
1058 /*------------------------------------------------------------------*/
1059 int checkDecl ( symbol *sym )
1062 checkSClass (sym); /* check the storage class */
1063 changePointer(sym); /* change pointers if required */
1065 /* if this is an array without any dimension
1066 then update the dimension from the initial value */
1067 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1068 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1073 /*------------------------------------------------------------------*/
1074 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1075 /*------------------------------------------------------------------*/
1076 sym_link *copyLinkChain ( sym_link *p)
1078 sym_link *head, *curr , *loop;
1081 head = loop = ( curr ? newLink() : (void *) NULL) ;
1083 memcpy(loop,curr,sizeof(sym_link)) ; /* copy it */
1084 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1093 /*------------------------------------------------------------------*/
1094 /* cleanUpBlock - cleansup the symbol table specified for all the */
1095 /* symbols in the given block */
1096 /*------------------------------------------------------------------*/
1097 void cleanUpBlock ( bucket **table, int block)
1102 /* go thru the entire table */
1103 for ( i = 0 ; i < 256; i++ ) {
1104 for ( chain = table[i]; chain ; chain = chain->next ) {
1105 if (chain->block >= block) {
1106 deleteSym (table,chain->sym,chain->name);
1112 /*------------------------------------------------------------------*/
1113 /* cleanUpLevel - cleansup the symbol table specified for all the */
1114 /* symbols in the given level */
1115 /*------------------------------------------------------------------*/
1116 void cleanUpLevel (bucket **table, int level )
1121 /* go thru the entire table */
1122 for ( i = 0 ; i < 256; i++ ) {
1123 for ( chain = table[i]; chain ; chain = chain->next ) {
1124 if (chain->level >= level) {
1125 deleteSym (table,chain->sym,chain->name);
1131 /*------------------------------------------------------------------*/
1132 /* computeType - computes the resultant type from two types */
1133 /*------------------------------------------------------------------*/
1134 sym_link *computeType ( sym_link *type1, sym_link *type2)
1138 sym_link *etype1 = getSpec(type1);
1139 sym_link *etype2 = getSpec(type2);
1141 /* if one of them is a float then result is a float */
1142 /* here we assume that the types passed are okay */
1143 /* and can be cast to one another */
1144 /* which ever is greater in size */
1145 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1146 rType = newFloatLink();
1148 /* if only one of them is a bit variable
1149 then the other one prevails */
1150 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1151 rType = copyLinkChain(type2);
1153 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1154 rType = copyLinkChain(type1);
1156 /* if one of them is a pointer then that
1159 rType = copyLinkChain(type1);
1162 rType = copyLinkChain(type2);
1164 if (getSize (type1) > getSize(type2) )
1165 rType = copyLinkChain(type1);
1167 rType = copyLinkChain(type2);
1169 reType = getSpec(rType);
1171 /* if either of them unsigned then make this unsigned */
1172 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1173 SPEC_USIGN(reType) = 1;
1175 /* if result is a literal then make not so */
1176 if (IS_LITERAL(reType))
1177 SPEC_SCLS(reType) = S_REGISTER ;
1182 /*------------------------------------------------------------------*/
1183 /* checkType - will do type check return 1 if match */
1184 /*------------------------------------------------------------------*/
1185 int checkType ( sym_link *dest, sym_link *src )
1196 /* if dest is a declarator then */
1197 if (IS_DECL(dest)) {
1199 if (DCL_TYPE(src) == DCL_TYPE(dest))
1200 return checkType(dest->next,src->next);
1202 if (IS_PTR(src) && IS_PTR(dest))
1205 if (IS_PTR(dest) && IS_ARRAY(src))
1208 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1209 return -1 * checkType (dest->next,src) ;
1214 if (IS_PTR(dest) && IS_INTEGRAL(src))
1220 /* if one is a specifier and the other is not */
1221 if ((IS_SPEC(src) && !IS_SPEC(dest)) ||
1222 (IS_SPEC(dest) && !IS_SPEC(src))) return 0;
1224 /* if one of them is a void then ok */
1225 if (SPEC_NOUN(dest) == V_VOID &&
1226 SPEC_NOUN(src) != V_VOID )
1229 if (SPEC_NOUN(dest) != V_VOID &&
1230 SPEC_NOUN(src) == V_VOID )
1233 /* char === to short */
1234 if (SPEC_NOUN(dest) == V_CHAR &&
1235 SPEC_NOUN(src) == V_INT &&
1237 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1239 if (SPEC_NOUN(src) == V_CHAR &&
1240 SPEC_NOUN(dest) == V_INT &&
1242 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1244 /* if they are both bitfields then if the lengths
1245 and starts don't match */
1246 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1247 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1248 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1251 /* it is a specifier */
1252 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1253 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1254 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1255 getSize(dest) == getSize(src))
1258 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1264 if (IS_STRUCT(dest)) {
1265 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1270 if (SPEC_LONG(dest) != SPEC_LONG(src))
1273 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1276 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1282 /*------------------------------------------------------------------*/
1283 /* inCalleeSaveList - return 1 if found in calle save list */
1284 /*------------------------------------------------------------------*/
1285 bool inCalleeSaveList ( char *s)
1289 for (i = 0 ; options.calleeSaves[i] ; i++ )
1290 if (strcmp(options.calleeSaves[i],s) == 0)
1296 /*-----------------------------------------------------------------*/
1297 /* aggregateArgToPointer: change an agggregate type function */
1298 /* argument to a pointer to that type. */
1299 /*-----------------------------------------------------------------*/
1300 void aggregateArgToPointer(value *val)
1302 if ( IS_AGGREGATE(val->type)) {
1303 /* if this is a structure */
1304 /* then we need to add a new link */
1305 if (IS_STRUCT(val->type)) {
1306 /* first lets add DECLARATOR type */
1307 sym_link *p = val->type ;
1309 werror(W_STRUCT_AS_ARG,val->name);
1310 val->type = newLink();
1311 val->type->next = p ;
1314 /* change to a pointer depending on the */
1315 /* storage class specified */
1316 switch (SPEC_SCLS(val->etype)) {
1318 DCL_TYPE(val->type) = IPOINTER;
1321 DCL_TYPE(val->type) = PPOINTER;
1326 /* The AUTO and REGISTER classes should probably
1327 * also become generic pointers, but I haven't yet
1328 * devised a test case for that.
1330 DCL_TYPE(val->type) = GPOINTER;
1337 DCL_TYPE(val->type) = POINTER ;
1340 DCL_TYPE(val->type) = CPOINTER;
1343 DCL_TYPE(val->type) = FPOINTER;
1346 DCL_TYPE(val->type) = EEPPOINTER;
1349 DCL_TYPE(val->type) = GPOINTER;
1352 /* is there is a symbol associated then */
1353 /* change the type of the symbol as well*/
1355 val->sym->type = copyLinkChain(val->type);
1356 val->sym->etype = getSpec(val->sym->type);
1360 /*------------------------------------------------------------------*/
1361 /* checkFunction - does all kinds of check on a function */
1362 /*------------------------------------------------------------------*/
1363 int checkFunction (symbol *sym)
1366 value *exargs, *acargs ;
1369 /* if not type then some kind of error */
1373 /* if the function has no type then make it return int */
1374 if ( !sym->type->next )
1375 sym->type->next = sym->etype = newIntLink();
1377 /* function cannot return aggregate */
1378 if (IS_AGGREGATE(sym->type->next)) {
1379 werror(E_FUNC_AGGR,sym->name);
1383 /* function cannot return bit */
1384 if (IS_BITVAR(sym->type->next)) {
1385 werror(E_FUNC_BIT,sym->name);
1389 /* check if this function is defined as calleeSaves
1390 then mark it as such */
1391 sym->calleeSave = inCalleeSaveList(sym->name);
1393 /* if interrupt service routine */
1394 /* then it cannot have arguments */
1395 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1396 werror(E_INT_ARGS,sym->name);
1400 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1401 return 1 ; /* not defined nothing more to check */
1403 /* check if body already present */
1404 if ( csym && csym->fbody ) {
1405 werror(E_FUNC_BODY,sym->name);
1409 /* check the return value type */
1410 if (checkType (csym->type,sym->type) <= 0) {
1411 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1412 werror (E_CONTINUE,"previous defintion type ");
1413 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1414 werror (E_CONTINUE,"current definition type ");
1415 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1419 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1420 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1424 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1425 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1429 /* compare expected agrs with actual args */
1430 exargs = csym->args ;
1431 acargs = sym->args ;
1433 /* for all the expected args do */
1436 exargs = exargs->next, acargs = acargs->next, argCnt++ )
1439 /* If the actual argument is an array, any prototype
1440 * will have modified it to a pointer. Duplicate that
1443 if ( IS_AGGREGATE(acargs->type))
1445 checkValue = copyValue(acargs);
1446 aggregateArgToPointer(checkValue);
1450 checkValue = acargs;
1453 if ( checkType(exargs->type,checkValue->type) <= 0)
1455 werror(E_ARG_TYPE,argCnt);
1460 /* if one them ended we have a problem */
1461 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1462 (!exargs && acargs && !IS_VOID(acargs->type)))
1463 werror(E_ARG_COUNT);
1465 /* replace with this defition */
1466 sym->cdef = csym->cdef;
1467 deleteSym (SymbolTab,csym,csym->name);
1468 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1469 if (IS_EXTERN(csym->etype) && !
1470 IS_EXTERN(sym->etype)) {
1471 addSet(&publics,sym);
1476 /*-----------------------------------------------------------------*/
1477 /* processFuncArgs - does some processing with function args */
1478 /*-----------------------------------------------------------------*/
1479 void processFuncArgs (symbol *func, int ignoreName)
1485 /* if this function has variable argument list */
1486 /* then make the function a reentrant one */
1488 SPEC_RENT(func->etype) = 1;
1490 /* check if this function is defined as calleeSaves
1491 then mark it as such */
1492 func->calleeSave = inCalleeSaveList(func->name);
1494 val = func->args; /* loop thru all the arguments */
1496 /* if it is void then remove parameters */
1497 if (val && IS_VOID(val->type)) {
1502 /* reset regparm for the port */
1503 (*port->reset_regparms)();
1504 /* if any of the arguments is an aggregate */
1505 /* change it to pointer to the same type */
1507 /* mark it as a register parameter if
1508 the function does not have VA_ARG
1509 and as port dictates
1510 not inhibited by command line option or #pragma */
1511 if (!func->hasVargs &&
1512 !options.noregparms &&
1513 !IS_RENT(func->etype) &&
1514 (*port->reg_parm)(val->type)) {
1515 SPEC_REGPARM(val->etype) = 1;
1518 if ( IS_AGGREGATE(val->type)) {
1519 aggregateArgToPointer(val);
1525 /* if this function is reentrant or */
1526 /* automatics r 2b stacked then nothing */
1527 if (IS_RENT(func->etype) || options.stackAuto )
1534 /* if a symbolname is not given */
1535 /* synthesize a variable name */
1538 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1539 val->sym = newSymbol(val->name,1);
1540 SPEC_OCLS(val->etype) = port->mem.default_local_map;
1541 val->sym->type = copyLinkChain (val->type);
1542 val->sym->etype = getSpec (val->sym->type);
1543 val->sym->_isparm = 1;
1544 strcpy (val->sym->rname,val->name);
1545 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1546 SPEC_STAT(func->etype);
1547 addSymChain(val->sym);
1550 else /* symbol name given create synth name */ {
1552 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1553 strcpy (val->sym->rname,val->name);
1554 val->sym->_isparm = 1;
1555 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1556 (options.model != MODEL_SMALL ? xdata : data);
1557 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1558 SPEC_STAT(func->etype);
1564 /*-----------------------------------------------------------------*/
1565 /* isSymbolEqual - compares two symbols return 1 if they match */
1566 /*-----------------------------------------------------------------*/
1567 int isSymbolEqual (symbol *dest, symbol *src)
1569 /* if pointers match then equal */
1573 /* if one of them is null then don't match */
1577 /* if both of them have rname match on rname */
1578 if (dest->rname[0] && src->rname[0])
1579 return (!strcmp(dest->rname,src->rname));
1581 /* otherwise match on name */
1582 return (!strcmp(dest->name,src->name));
1585 /*-----------------------------------------------------------------*/
1586 /* printTypeChain - prints the type chain in human readable form */
1587 /*-----------------------------------------------------------------*/
1588 void printTypeChain (sym_link *type, FILE *of)
1598 if (IS_DECL(type)) {
1599 switch (DCL_TYPE(type)) {
1601 fprintf (of,"function ");
1604 fprintf (of,"_generic * ");
1605 if (DCL_PTR_CONST(type))
1606 fprintf(of,"const ");
1609 fprintf (of,"_code * ");
1610 if (DCL_PTR_CONST(type))
1611 fprintf(of,"const ");
1614 fprintf (of,"_far * ");
1615 if (DCL_PTR_CONST(type))
1616 fprintf(of,"const ");
1619 fprintf (of,"_eeprom * ");
1620 if (DCL_PTR_CONST(type))
1621 fprintf(of,"const ");
1625 fprintf (of,"_near * ");
1626 if (DCL_PTR_CONST(type))
1627 fprintf(of,"const ");
1630 fprintf (of,"_idata *");
1631 if (DCL_PTR_CONST(type))
1632 fprintf(of,"const ");
1635 fprintf (of,"_pdata *");
1636 if (DCL_PTR_CONST(type))
1637 fprintf(of,"const ");
1640 fprintf (of," _unkown *");
1641 if (DCL_PTR_CONST(type))
1642 fprintf(of,"const ");
1646 fprintf (of,"array of ");
1650 if (SPEC_VOLATILE(type))
1651 fprintf (of,"volatile ");
1652 if (SPEC_USIGN(type))
1653 fprintf (of,"unsigned ");
1655 switch (SPEC_NOUN(type)) {
1658 fprintf (of,"long ");
1661 fprintf (of,"short ");
1663 fprintf (of,"int ");
1667 fprintf(of,"char ");
1671 fprintf(of,"void ");
1675 fprintf(of,"float ");
1679 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1683 fprintf(of,"sbit ");
1687 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1700 /*-----------------------------------------------------------------*/
1701 /* cdbTypeInfo - print the type information for debugger */
1702 /*-----------------------------------------------------------------*/
1703 void cdbTypeInfo (sym_link *type,FILE *of)
1705 fprintf(of,"{%d}",getSize(type));
1707 if (IS_DECL(type)) {
1708 switch (DCL_TYPE(type)) {
1734 fprintf (of,"DA%d,",DCL_ELEM(type));
1740 switch (SPEC_NOUN(type)) {
1764 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1772 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1779 if (SPEC_USIGN(type))
1787 /*-----------------------------------------------------------------*/
1788 /* cdbSymbol - prints a symbol & its type information for debugger */
1789 /*-----------------------------------------------------------------*/
1790 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1802 fprintf(of,"S:"); /* symbol record */
1803 /* if this is not a structure symbol then
1804 we need to figure out the scope information */
1808 if (IS_STATIC(sym->etype))
1809 fprintf(of,"F%s$",moduleName); /* scope is file */
1811 fprintf(of,"G$"); /* scope is global */
1814 /* symbol is local */
1815 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1817 fprintf(of,"S$"); /* scope is structure */
1819 /* print the name, & mangled name */
1820 fprintf(of,"%s$%d$%d(",sym->name,
1821 sym->level,sym->block);
1823 cdbTypeInfo(sym->type,of);
1826 /* print the address space */
1827 map = SPEC_OCLS(sym->etype);
1828 fprintf(of,"%c,%d,%d",
1829 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1831 /* if assigned to registers then output register names */
1832 /* if this is a function then print
1833 if is it an interrupt routine & interrupt number
1834 and the register bank it is using */
1836 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1837 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1838 /* alternate location to find this symbol @ : eg registers
1845 /*-----------------------------------------------------------------*/
1846 /* cdbStruct - print a structure for debugger */
1847 /*-----------------------------------------------------------------*/
1848 void cdbStruct ( structdef *sdef,int block,FILE *of,
1849 int inStruct, char *tag)
1854 /* if block # then must have function scope */
1855 fprintf(of,"F%s$",moduleName);
1856 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1857 for (sym=sdef->fields ; sym ; sym = sym->next) {
1858 fprintf(of,"({%d}",sym->offset);
1859 cdbSymbol(sym,of,TRUE,FALSE);
1867 /*------------------------------------------------------------------*/
1868 /* cdbStructBlock - calls struct printing for a blcks */
1869 /*------------------------------------------------------------------*/
1870 void cdbStructBlock (int block , FILE *of)
1873 bucket **table = StructTab;
1877 /* go thru the entire table */
1878 for ( i = 0 ; i < 256; i++ ) {
1879 for ( chain = table[i]; chain ; chain = chain->next ) {
1880 if (chain->block >= block) {
1881 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1887 /*-----------------------------------------------------------------*/
1888 /* powof2 - returns power of two for the number if number is pow 2 */
1889 /*-----------------------------------------------------------------*/
1890 int powof2 (unsigned long num)
1896 if (num & 1) n1s++ ;
1901 if (n1s > 1 || nshifts == 0) return 0;
1902 return nshifts - 1 ;
1916 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1917 symbol *__muldiv[3][3][2];
1918 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1919 sym_link *__multypes[3][2];
1920 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1921 symbol *__conv[2][3][2];
1923 sym_link *floatType;
1925 static void _makeRegParam(symbol *sym)
1929 val = sym->args; /* loop thru all the arguments */
1931 /* reset regparm for the port */
1932 (*port->reset_regparms)();
1934 SPEC_REGPARM(val->etype) = 1;
1935 sym->argStack -= getSize(val->type);
1940 /*-----------------------------------------------------------------*/
1941 /* initCSupport - create functions for C support routines */
1942 /*-----------------------------------------------------------------*/
1943 void initCSupport ()
1945 const char *smuldivmod[] = {
1948 const char *sbwd[] = {
1949 "char", "int", "long"
1951 const char *ssu[] = {
1955 int bwd, su, muldivmod, tofrom;
1957 floatType= newFloatLink();
1959 for (bwd = 0; bwd < 3; bwd++) {
1974 __multypes[bwd][0] = l;
1975 __multypes[bwd][1] = copyLinkChain(l);
1976 SPEC_USIGN(__multypes[bwd][1]) = 1;
1979 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1980 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1981 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1982 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1983 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1984 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1985 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1986 __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1987 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1988 __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1990 for (tofrom = 0; tofrom < 2; tofrom++) {
1991 for (bwd = 0; bwd < 3; bwd++) {
1992 for (su = 0; su < 2; su++) {
1994 sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1995 __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1998 sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1999 __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
2005 for (muldivmod = 0; muldivmod < 3; muldivmod++) {
2006 for (bwd = 0; bwd < 3; bwd++) {
2007 for (su = 0; su < 2; su++) {
2008 sprintf(buffer, "_%s%s%s",
2009 smuldivmod[muldivmod],
2012 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
2013 SPEC_NONBANKED(__muldiv[muldivmod][bwd][su]->etype) = 1;
2014 if (bwd < port->muldiv.force_reg_param_below)
2015 _makeRegParam(__muldiv[muldivmod][bwd][su]);