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 -------------------------------------------------------------------------*/
26 bucket *SymbolTab [256] ; /* the symbol table */
27 bucket *StructTab [256] ; /* the structure table */
28 bucket *TypedefTab[256] ; /* the typedef table */
29 bucket *LabelTab [256] ; /* the Label table */
30 bucket *enumTab [256] ; /* enumerated table */
32 extern struct set *publics;
34 /*------------------------------------------------------------------*/
35 /* initSymt () - initialises symbol table related stuff */
36 /*------------------------------------------------------------------*/
41 for ( i = 0 ; i < 256 ; i++ )
42 SymbolTab[i] = StructTab[i] = (void *) NULL ;
46 /*-----------------------------------------------------------------*/
47 /* newBucket - allocates & returns a new bucket */
48 /*-----------------------------------------------------------------*/
53 ALLOC(bp,sizeof(bucket));
58 /*-----------------------------------------------------------------*/
59 /* hashKey - computes the hashkey given a symbol name */
60 /*-----------------------------------------------------------------*/
61 int hashKey (const char *s)
63 unsigned long key = 0;
70 /*-----------------------------------------------------------------*/
71 /* addSym - adds a symbol to the hash Table */
72 /*-----------------------------------------------------------------*/
73 void addSym ( bucket **stab ,
79 int i ; /* index into the hash Table */
80 bucket *bp ; /* temp bucket * */
82 /* the symbols are always added at the head of the list */
84 /* get a free entry */
85 ALLOC(bp,sizeof(bucket));
87 bp->sym = sym ; /* update the symbol pointer */
88 bp->level = level; /* update the nest level */
90 strcpy(bp->name,sname); /* copy the name into place */
92 /* if this is the first entry */
93 if (stab[i] == NULL) {
94 bp->prev = bp->next = (void *) NULL ; /* point to nothing */
97 /* not first entry then add @ head of list */
106 /*-----------------------------------------------------------------*/
107 /* deleteSym - deletes a symbol from the hash Table entry */
108 /*-----------------------------------------------------------------*/
109 void deleteSym ( bucket **stab, void *sym, char *sname)
117 /* find the symbol */
119 if (bp->sym == sym) /* found it then break out */
120 break ; /* of the loop */
124 if (!bp) /* did not find it */
126 /* if this is the first one in the chain */
129 if ( stab[i] ) /* if chain ! empty */
130 stab[i]->prev = (void *) NULL ;
132 /* middle || end of chain */
134 if ( bp->next ) /* if not end of chain */
135 bp->next->prev = bp->prev ;
137 bp->prev->next = bp->next ;
142 /*-----------------------------------------------------------------*/
143 /* findSym - finds a symbol in a table */
144 /*-----------------------------------------------------------------*/
145 void *findSym ( bucket **stab, void *sym, const char *sname)
149 bp = stab[hashKey(sname)] ;
152 if ( bp->sym == sym || strcmp (bp->name,sname) == 0 )
157 return ( bp ? bp->sym : (void *) NULL ) ;
160 /*-----------------------------------------------------------------*/
161 /* findSymWithLevel - finds a symbol with a name & level */
162 /*-----------------------------------------------------------------*/
163 void *findSymWithLevel ( bucket **stab, symbol *sym)
167 bp = stab[hashKey(sym->name)];
170 ** do the search from the head of the list since the
171 ** elements are added at the head it is ensured that
172 ** we will find the deeper definitions before we find
173 ** the global ones. we need to check for symbols with
174 ** level <= to the level given, if levels match then block
175 ** numbers need to match as well
179 if ( strcmp(bp->name,sym->name) == 0 && bp->level <= sym->level) {
180 /* if this is parameter then nothing else need to be checked */
181 if (((symbol *)(bp->sym))->_isparm)
183 /* if levels match then block numbers hsould also match */
184 if (bp->level && bp->level == sym->level && bp->block == sym->block )
186 /* if levels don't match then we are okay */
187 if (bp->level && bp->level != sym->level)
189 /* if this is a global variable then we are ok too */
197 return (void *) NULL ;
200 /*-----------------------------------------------------------------*/
201 /* findSymWithBlock - finds a symbol with name in with a block */
202 /*-----------------------------------------------------------------*/
203 void *findSymWithBlock ( bucket **stab, symbol *sym, int block)
207 bp = stab[hashKey(sym->name)] ;
210 if ( strcmp (bp->name,sym->name) == 0 &&
216 return ( bp ? bp->sym : (void *) NULL ) ;
219 /*------------------------------------------------------------------*/
220 /* newSymbol () - returns a new pointer to a symbol */
221 /*------------------------------------------------------------------*/
222 symbol *newSymbol (char *name, int scope )
226 ALLOC(sym,sizeof(symbol));
228 strcpy(sym->name,name); /* copy the name */
229 sym->level = scope ; /* set the level */
230 sym->block = currBlockno ;
231 sym->lineDef = yylineno ; /* set the line number */
235 /*------------------------------------------------------------------*/
236 /* newLink - creates a new link (declarator,specifier) */
237 /*------------------------------------------------------------------*/
242 ALLOC(p,sizeof(link));
247 /*------------------------------------------------------------------*/
248 /* newStruct - creats a new structdef from the free list */
249 /*------------------------------------------------------------------*/
250 structdef *newStruct ( char *tag )
254 ALLOC(s,sizeof(structdef));
256 strcpy(s->tag,tag) ; /* copy the tag */
260 /*------------------------------------------------------------------*/
261 /* pointerTypes - do the computation for the pointer types */
262 /*------------------------------------------------------------------*/
263 void pointerTypes (link *ptr, link *type)
268 /* find the first pointer type */
269 while (ptr && !IS_PTR(ptr))
272 /* could not find it */
273 if (!ptr || IS_SPEC(ptr) ||
274 DCL_TYPE(ptr) != UPOINTER)
277 /* change the pointer type depending on the
278 storage class of the type */
280 DCL_PTR_CONST(ptr) = SPEC_CONST(type);
281 DCL_PTR_VOLATILE(ptr) = SPEC_VOLATILE(type);
282 switch (SPEC_SCLS(type)) {
284 DCL_TYPE(ptr) = FPOINTER;
287 DCL_TYPE(ptr) = IPOINTER ;
290 DCL_TYPE(ptr) = PPOINTER ;
293 DCL_TYPE(ptr) = POINTER ;
296 DCL_PTR_CONST(ptr) = port->mem.code_ro;
297 DCL_TYPE(ptr) = CPOINTER ;
300 DCL_TYPE(ptr) = EEPPOINTER;
303 DCL_TYPE(ptr) = GPOINTER;
306 /* the storage class of type ends here */
309 SPEC_VOLATILE(type) = 0;
312 /* now change all the remaining unknown pointers
313 to generic pointers */
315 if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER)
316 DCL_TYPE(ptr) = GPOINTER;
320 /* same for the type although it is highly unlikely that
321 type will have a pointer */
323 if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER)
324 DCL_TYPE(type) = GPOINTER;
330 /*------------------------------------------------------------------*/
331 /* addDecl - adds a declarator @ the end of a chain */
332 /*------------------------------------------------------------------*/
333 void addDecl ( symbol *sym, int type , link *p )
339 /* if we are passed a link then set head & tail */
346 head = tail = newLink() ;
347 DCL_TYPE(head) = type ;
350 /* if this is the first entry */
356 if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) {
357 sym->etype = mergeSpec(sym->etype,head);
360 if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) {
362 while (t->next != sym->etype) t = t->next ;
364 tail->next = sym->etype;
366 sym->etype->next = head;
372 /* if the type is a unknown pointer and has
373 a tspec then take the storage class const & volatile
374 attribute from the tspec & make it those of this
378 DCL_TYPE(p) == UPOINTER &&
380 if (!IS_SPEC(sym->etype)) {
381 sym->etype = sym->etype->next = newLink();
382 sym->etype->class = SPECIFIER;
384 SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p));
385 SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p));
386 SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p));
392 /*------------------------------------------------------------------*/
393 /* mergeSpec - merges two specifiers and returns the new one */
394 /*------------------------------------------------------------------*/
395 link *mergeSpec ( link *dest, link *src )
397 /* if noun different then src overrides */
398 if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest))
399 SPEC_NOUN(dest) = SPEC_NOUN(src) ;
401 if (! SPEC_SCLS(dest)) /* if destination has no storage class */
402 SPEC_SCLS(dest) = SPEC_SCLS(src) ;
404 /* copy all the specifications */
405 SPEC_LONG(dest) |= SPEC_LONG(src);
406 SPEC_SHORT(dest) |= SPEC_SHORT(src);
407 SPEC_USIGN(dest) |= SPEC_USIGN(src);
408 SPEC_STAT(dest) |= SPEC_STAT(src);
409 SPEC_EXTR(dest) |= SPEC_EXTR(src);
410 SPEC_ABSA(dest) |= SPEC_ABSA(src);
411 SPEC_RENT(dest) |= SPEC_RENT(src);
412 SPEC_INTN(dest) |= SPEC_INTN(src);
413 SPEC_BANK(dest) |= SPEC_BANK(src);
414 SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src);
415 SPEC_CRTCL(dest) |= SPEC_CRTCL(src);
416 SPEC_ADDR(dest) |= SPEC_ADDR(src);
417 SPEC_OCLS(dest) = SPEC_OCLS(src);
418 SPEC_BLEN(dest) |= SPEC_BLEN(src);
419 SPEC_BSTR(dest) |= SPEC_BSTR(src);
420 SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src);
421 SPEC_NONBANKED(dest) |= SPEC_NONBANKED(src);
423 if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL )
424 SPEC_STRUCT(dest) = SPEC_STRUCT(src);
429 /*------------------------------------------------------------------*/
430 /* cloneSpec - copies the entire spec and returns a new spec */
431 /*------------------------------------------------------------------*/
432 link *cloneSpec ( link *src )
436 /* go thru chain till we find the specifier */
437 while ( src && src->class != SPECIFIER )
441 memcpy (spec,src,sizeof(link));
445 /*------------------------------------------------------------------*/
446 /* genSymName - generates and returns a name used for anonymous vars*/
447 /*------------------------------------------------------------------*/
448 char *genSymName ( int level )
450 static int gCount = 0 ;
451 static char gname[SDCC_NAME_MAX+1] ;
453 sprintf (gname,"__%04d%04d",level,gCount++);
457 /*------------------------------------------------------------------*/
458 /* getSpec - returns the specifier part from a declaration chain */
459 /*------------------------------------------------------------------*/
460 link *getSpec ( link *p )
465 while ( p && ! (IS_SPEC(p)))
471 /*------------------------------------------------------------------*/
472 /* newCharLink() - creates an int type */
473 /*------------------------------------------------------------------*/
479 p->class = SPECIFIER ;
480 SPEC_NOUN(p) = V_CHAR ;
485 /*------------------------------------------------------------------*/
486 /* newFloatLink - a new Float type */
487 /*------------------------------------------------------------------*/
493 p->class = SPECIFIER ;
494 SPEC_NOUN(p) = V_FLOAT ;
499 /*------------------------------------------------------------------*/
500 /* newLongLink() - new long type */
501 /*------------------------------------------------------------------*/
507 p->class = SPECIFIER ;
508 SPEC_NOUN(p) = V_INT ;
514 /*------------------------------------------------------------------*/
515 /* newIntLink() - creates an int type */
516 /*------------------------------------------------------------------*/
522 p->class = SPECIFIER ;
523 SPEC_NOUN(p) = V_INT ;
528 /*------------------------------------------------------------------*/
529 /* getSize - returns size of a type chain in bits */
530 /*------------------------------------------------------------------*/
531 unsigned int getSize ( link *p )
533 /* if nothing return 0 */
536 if ( IS_SPEC(p) ) { /* if this is the specifier then */
537 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
539 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
547 return SPEC_STRUCT(p)->size ;
553 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
559 /* this is a specifier */
560 switch (DCL_TYPE(p)) {
564 return DCL_ELEM(p) * getSize (p->next) ;
581 /*------------------------------------------------------------------*/
582 /* bitsForType - returns # of bits required to store this type */
583 /*------------------------------------------------------------------*/
584 unsigned int bitsForType ( link *p )
586 /* if nothing return 0 */
590 if ( IS_SPEC(p) ) { /* if this is the specifier then */
592 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
594 return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
602 return SPEC_STRUCT(p)->size*8 ;
614 /* this is a specifier */
615 switch (DCL_TYPE(p)) {
619 return DCL_ELEM(p) * getSize (p->next) *8 ;
623 return ( PTRSIZE * 8) ;
627 return ( FPTRSIZE * 8);
629 return ( GPTRSIZE * 8);
636 /*------------------------------------------------------------------*/
637 /* copySymbolChain - copies a symbol chain */
638 /*------------------------------------------------------------------*/
639 symbol *copySymbolChain (symbol *src)
646 dest = copySymbol(src);
647 dest->next = copySymbolChain(src->next);
651 /*------------------------------------------------------------------*/
652 /* copySymbol - makes a copy of a symbol */
653 /*------------------------------------------------------------------*/
654 symbol *copySymbol (symbol *src)
661 dest = newSymbol( src->name, src->level );
662 memcpy(dest,src,sizeof(symbol));
663 dest->level = src->level ;
664 dest->block = src->block ;
665 dest->ival = copyIlist(src->ival);
666 dest->type = copyLinkChain(src->type);
667 dest->etype= getSpec(dest->type);
669 dest->args = copyValueChain (src->args);
670 dest->key = src->key;
671 dest->calleeSave = src->calleeSave;
672 dest->allocreq = src->allocreq;
676 /*------------------------------------------------------------------*/
677 /* reverseSyms - reverses the links for a symbol chain */
678 /*------------------------------------------------------------------*/
679 symbol *reverseSyms ( symbol *sym)
681 symbol *prev , *curr, *next ;
696 sym->next = (void *) NULL ;
700 /*------------------------------------------------------------------*/
701 /* reverseLink - reverses the links for a type chain */
702 /*------------------------------------------------------------------*/
703 link *reverseLink ( link *type)
705 link *prev , *curr, *next ;
720 type->next = (void *) NULL ;
724 /*------------------------------------------------------------------*/
725 /* addSymChain - adds a symbol chain to the symboltable */
726 /*------------------------------------------------------------------*/
727 void addSymChain ( symbol *symHead )
729 symbol *sym = symHead ;
730 symbol *csym = NULL ;
732 for (;sym != NULL ; sym = sym->next ) {
734 /* if already exists in the symbol table then check if
735 the previous was an extern definition if yes then
736 then check if the type match, if the types match then
737 delete the current entry and add the new entry */
738 if ((csym = findSymWithLevel (SymbolTab,sym)) &&
739 csym->level == sym->level) {
741 /* previous definition extern ? */
742 if ( IS_EXTERN(csym->etype) ) {
743 /* do types match ? */
744 if (checkType ( csym->type,sym->type) != 1)
746 werror (E_DUPLICATE,csym->name);
748 /* delete current entry */
749 deleteSym (SymbolTab, csym, csym->name );
751 addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
752 } else /* not extern */
753 werror(E_DUPLICATE,sym->name) ;
757 /* check if previously defined */
758 if (csym && csym->level == sym->level ) {
759 /* if the previous one was declared as extern */
760 /* then check the type with the current one */
761 if ( IS_EXTERN(csym->etype) ) {
762 if ( checkType (csym->type, sym->type ) <= 0 )
763 werror (W_EXTERN_MISMATCH,csym->name);
767 addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
772 /*------------------------------------------------------------------*/
773 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
774 /*------------------------------------------------------------------*/
775 int funcInChain (link *lnk)
785 /*------------------------------------------------------------------*/
786 /* structElemType - returns the type info of a sturct member */
787 /*------------------------------------------------------------------*/
788 link *structElemType (link *stype, value *id ,value **argsp)
790 symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
792 if ( ! fields || ! id)
795 /* look for the id */
797 if (strcmp(fields->rname,id->name) == 0) {
799 *argsp = fields->args;
801 return copyLinkChain (fields->type) ;
803 fields = fields->next ;
805 werror(E_NOT_MEMBER,id->name);
810 /*------------------------------------------------------------------*/
811 /* getStructElement - returns element of a tructure definition */
812 /*------------------------------------------------------------------*/
813 symbol *getStructElement ( structdef *sdef, symbol *sym)
817 for ( field = sdef->fields ; field ; field = field->next )
818 if ( strcmp(field->name,sym->name) == 0)
821 werror(E_NOT_MEMBER,sym->name);
823 return sdef->fields ;
826 /*------------------------------------------------------------------*/
827 /* compStructSize - computes the size of a structure */
828 /*------------------------------------------------------------------*/
829 int compStructSize (int su, structdef *sdef )
831 int sum = 0 , usum =0;
835 /* for the identifiers */
836 loop = sdef->fields ;
839 /* create the internal name for this variable */
840 sprintf (loop->rname,"_%s",loop->name);
841 loop->offset = ( su == UNION ? sum = 0 : sum ) ;
842 SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
844 /* if this is a bit field */
847 /* change it to a unsigned bit */
848 SPEC_NOUN(loop->etype) = V_BIT ;
849 SPEC_USIGN(loop->etype) = 1 ;
850 /* check if this fit into the remaining */
851 /* bits of this byte else align it to the */
852 /* next byte boundary */
853 if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset)) {
854 SPEC_BSTR(loop->etype) = bitOffset ;
855 sum += (loop->bitVar / 8) ;
856 bitOffset += (loop->bitVar % 8);
858 else /* does not fit */
861 loop->offset++; /* go to the next byte */
863 SPEC_BSTR(loop->etype) = bitOffset ;
864 sum += (loop->bitVar / 8) ;
865 bitOffset += (loop->bitVar % 8);
867 /* if this is the last field then pad */
868 if (!loop->next && bitOffset) {
875 sum += getSize (loop->type) ;
878 /* if function then do the arguments for it */
879 if (funcInChain(loop->type)) {
880 processFuncArgs (loop, 1);
885 /* if this is not a bitfield but the */
886 /* previous one was and did not take */
887 /* the whole byte then pad the rest */
888 if ((loop && !loop->bitVar) && bitOffset) {
893 /* if union then size = sizeof larget field */
895 usum = max(usum,sum);
899 return (su == UNION ? usum : sum);
902 /*------------------------------------------------------------------*/
903 /* checkSClass - check the storage class specification */
904 /*------------------------------------------------------------------*/
905 static void checkSClass ( symbol *sym )
907 /* type is literal can happen foe enums change
909 if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
910 SPEC_SCLS(sym->etype) = S_AUTO;
912 /* if sfr or sbit then must also be */
913 /* volatile the initial value will be xlated */
914 /* to an absolute address */
915 if (SPEC_SCLS(sym->etype) == S_SBIT ||
916 SPEC_SCLS(sym->etype) == S_SFR ) {
917 SPEC_VOLATILE(sym->etype) = 1;
918 /* if initial value given */
920 SPEC_ABSA(sym->etype) = 1;
921 SPEC_ADDR(sym->etype) =
922 (int) list2int(sym->ival);
927 /* if absolute address given then it mark it as
929 if (IS_ABSOLUTE(sym->etype))
930 SPEC_VOLATILE(sym->etype) = 1;
932 /* global variables declared const put into code */
933 if (sym->level == 0 &&
934 SPEC_SCLS(sym->etype) == S_CONSTANT) {
935 SPEC_SCLS(sym->etype) = S_CODE ;
936 SPEC_CONST(sym->etype) = 1;
939 /* global variable in code space is a constant */
940 if (sym->level == 0 &&
941 SPEC_SCLS(sym->etype) == S_CODE &&
943 SPEC_CONST(sym->etype) = 1;
946 /* if bit variable then no storage class can be */
947 /* specified since bit is already a storage */
948 if ( IS_BITVAR(sym->etype) &&
949 ( SPEC_SCLS(sym->etype) != S_FIXED &&
950 SPEC_SCLS(sym->etype) != S_SBIT &&
951 SPEC_SCLS(sym->etype) != S_BIT )
953 werror (E_BITVAR_STORAGE,sym->name);
954 SPEC_SCLS(sym->etype) = S_FIXED ;
957 /* extern variables cannot be initialized */
958 if (IS_EXTERN(sym->etype) && sym->ival) {
959 werror(E_EXTERN_INIT,sym->name);
963 /* if this is an automatic symbol then */
964 /* storage class will be ignored and */
965 /* symbol will be allocated on stack/ */
966 /* data depending on flag */
968 (options.stackAuto || reentrant ) &&
969 ( SPEC_SCLS(sym->etype) != S_AUTO &&
970 SPEC_SCLS(sym->etype) != S_FIXED &&
971 SPEC_SCLS(sym->etype) != S_REGISTER &&
972 SPEC_SCLS(sym->etype) != S_STACK &&
973 SPEC_SCLS(sym->etype) != S_XSTACK &&
974 SPEC_SCLS(sym->etype) != S_CONSTANT )) {
976 werror(E_AUTO_ASSUMED,sym->name) ;
977 SPEC_SCLS(sym->etype) = S_AUTO ;
980 /* automatic symbols cannot be given */
981 /* an absolute address ignore it */
983 SPEC_ABSA(sym->etype) &&
984 (options.stackAuto || reentrant) ) {
985 werror(E_AUTO_ABSA,sym->name);
986 SPEC_ABSA(sym->etype) = 0 ;
989 /* arrays & pointers cannot be defined for bits */
990 /* SBITS or SFRs or BIT */
991 if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
992 ( SPEC_NOUN(sym->etype) == V_BIT ||
993 SPEC_NOUN(sym->etype) == V_SBIT ||
994 SPEC_SCLS(sym->etype) == S_SFR ))
995 werror(E_BIT_ARRAY,sym->name);
997 /* if this is a bit|sbit then set length & start */
998 if (SPEC_NOUN(sym->etype) == V_BIT ||
999 SPEC_NOUN(sym->etype) == V_SBIT ) {
1000 SPEC_BLEN(sym->etype) = 1 ;
1001 SPEC_BSTR(sym->etype) = 0 ;
1004 /* variables declared in CODE space must have */
1005 /* initializers if not an extern */
1006 if (SPEC_SCLS(sym->etype) == S_CODE &&
1007 sym->ival == NULL &&
1009 port->mem.code_ro &&
1010 !IS_EXTERN(sym->etype))
1011 werror(E_CODE_NO_INIT,sym->name);
1013 /* if parameter or local variable then change */
1014 /* the storage class to reflect where the var will go */
1015 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1016 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1018 SPEC_SCLS(sym->etype) = (options.useXstack ?
1019 S_XSTACK : S_STACK ) ;
1023 /* hack-o-matic! I see no reason why the useXstack option should ever
1024 * control this allcoation, but the code was originally that way, and
1025 * changing it for non-390 ports breaks the compiler badly.
1027 extern PORT ds390_port;
1028 bool useXdata = (port == &ds390_port) ? options.model : options.useXstack;
1029 SPEC_SCLS(sym->etype) = (useXdata ?
1030 S_XDATA : S_FIXED ) ;
1035 /*------------------------------------------------------------------*/
1036 /* changePointer - change pointer to functions */
1037 /*------------------------------------------------------------------*/
1038 void changePointer (symbol *sym)
1042 /* go thru the chain of declarations */
1043 /* if we find a pointer to a function */
1044 /* unconditionally change it to a ptr */
1046 for ( p = sym->type ; p ; p = p->next) {
1047 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1048 DCL_TYPE(p) = GPOINTER ;
1049 if ( IS_PTR(p) && IS_FUNC(p->next))
1050 DCL_TYPE(p) = CPOINTER ;
1054 /*------------------------------------------------------------------*/
1055 /* checkDecl - does semantic validation of a declaration */
1056 /*------------------------------------------------------------------*/
1057 int checkDecl ( symbol *sym )
1060 checkSClass (sym); /* check the storage class */
1061 changePointer(sym); /* change pointers if required */
1063 /* if this is an array without any dimension
1064 then update the dimension from the initial value */
1065 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1066 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1071 /*------------------------------------------------------------------*/
1072 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1073 /*------------------------------------------------------------------*/
1074 link *copyLinkChain ( link *p)
1076 link *head, *curr , *loop;
1079 head = loop = ( curr ? newLink() : (void *) NULL) ;
1081 memcpy(loop,curr,sizeof(link)) ; /* copy it */
1082 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1091 /*------------------------------------------------------------------*/
1092 /* cleanUpBlock - cleansup the symbol table specified for all the */
1093 /* symbols in the given block */
1094 /*------------------------------------------------------------------*/
1095 void cleanUpBlock ( bucket **table, int block)
1100 /* go thru the entire table */
1101 for ( i = 0 ; i < 256; i++ ) {
1102 for ( chain = table[i]; chain ; chain = chain->next ) {
1103 if (chain->block >= block) {
1104 deleteSym (table,chain->sym,chain->name);
1110 /*------------------------------------------------------------------*/
1111 /* cleanUpLevel - cleansup the symbol table specified for all the */
1112 /* symbols in the given level */
1113 /*------------------------------------------------------------------*/
1114 void cleanUpLevel (bucket **table, int level )
1119 /* go thru the entire table */
1120 for ( i = 0 ; i < 256; i++ ) {
1121 for ( chain = table[i]; chain ; chain = chain->next ) {
1122 if (chain->level >= level) {
1123 deleteSym (table,chain->sym,chain->name);
1129 /*------------------------------------------------------------------*/
1130 /* computeType - computes the resultant type from two types */
1131 /*------------------------------------------------------------------*/
1132 link *computeType ( link *type1, link *type2)
1136 link *etype1 = getSpec(type1);
1137 link *etype2 = getSpec(type2);
1139 /* if one of them is a float then result is a float */
1140 /* here we assume that the types passed are okay */
1141 /* and can be cast to one another */
1142 /* which ever is greater in size */
1143 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1144 rType = newFloatLink();
1146 /* if only one of them is a bit variable
1147 then the other one prevails */
1148 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1149 rType = copyLinkChain(type2);
1151 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1152 rType = copyLinkChain(type1);
1154 /* if one of them is a pointer then that
1157 rType = copyLinkChain(type1);
1160 rType = copyLinkChain(type2);
1162 if (getSize (type1) > getSize(type2) )
1163 rType = copyLinkChain(type1);
1165 rType = copyLinkChain(type2);
1167 reType = getSpec(rType);
1169 /* if either of them unsigned then make this unsigned */
1170 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1171 SPEC_USIGN(reType) = 1;
1173 /* if result is a literal then make not so */
1174 if (IS_LITERAL(reType))
1175 SPEC_SCLS(reType) = S_REGISTER ;
1180 /*------------------------------------------------------------------*/
1181 /* checkType - will do type check return 1 if match */
1182 /*------------------------------------------------------------------*/
1183 int checkType ( link *dest, link *src )
1194 /* if dest is a declarator then */
1195 if (IS_DECL(dest)) {
1197 if (DCL_TYPE(src) == DCL_TYPE(dest))
1198 return checkType(dest->next,src->next);
1200 if (IS_PTR(src) && IS_PTR(dest))
1203 if (IS_PTR(dest) && IS_ARRAY(src))
1206 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1207 return -1 * checkType (dest->next,src) ;
1212 if (IS_PTR(dest) && IS_INTEGRAL(src))
1218 /* if one of them is a void then ok */
1219 if (SPEC_NOUN(dest) == V_VOID &&
1220 SPEC_NOUN(src) != V_VOID )
1223 if (SPEC_NOUN(dest) != V_VOID &&
1224 SPEC_NOUN(src) == V_VOID )
1227 /* char === to short */
1228 if (SPEC_NOUN(dest) == V_CHAR &&
1229 SPEC_NOUN(src) == V_INT &&
1231 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1233 if (SPEC_NOUN(src) == V_CHAR &&
1234 SPEC_NOUN(dest) == V_INT &&
1236 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1238 /* if they are both bitfields then if the lengths
1239 and starts don't match */
1240 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1241 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1242 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1245 /* it is a specifier */
1246 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1247 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1248 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1249 getSize(dest) == getSize(src))
1252 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1258 if (IS_STRUCT(dest)) {
1259 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1264 if (SPEC_LONG(dest) != SPEC_LONG(src))
1267 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1270 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1276 /*------------------------------------------------------------------*/
1277 /* inCalleeSaveList - return 1 if found in calle save list */
1278 /*------------------------------------------------------------------*/
1279 bool inCalleeSaveList ( char *s)
1283 for (i = 0 ; options.calleeSaves[i] ; i++ )
1284 if (strcmp(options.calleeSaves[i],s) == 0)
1290 /*------------------------------------------------------------------*/
1291 /* checkFunction - does all kinds of check on a function */
1292 /*------------------------------------------------------------------*/
1293 int checkFunction (symbol *sym)
1296 value *exargs, *acargs ;
1299 /* if not type then some kind of error */
1303 /* if the function has no type then make it return int */
1304 if ( !sym->type->next )
1305 sym->type->next = sym->etype = newIntLink();
1307 /* function cannot return aggregate */
1308 if (IS_AGGREGATE(sym->type->next)) {
1309 werror(E_FUNC_AGGR,sym->name);
1313 /* function cannot return bit */
1314 if (IS_BITVAR(sym->type->next)) {
1315 werror(E_FUNC_BIT,sym->name);
1319 /* check if this function is defined as calleeSaves
1320 then mark it as such */
1321 sym->calleeSave = inCalleeSaveList(sym->name);
1323 /* if interrupt service routine */
1324 /* then it cannot have arguments */
1325 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1326 werror(E_INT_ARGS,sym->name);
1330 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1331 return 1 ; /* not defined nothing more to check */
1333 /* check if body already present */
1334 if ( csym && csym->fbody ) {
1335 werror(E_FUNC_BODY,sym->name);
1339 /* check the return value type */
1340 if (checkType (csym->type,sym->type) <= 0) {
1341 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1342 werror (E_CONTINUE,"previous defintion type ");
1343 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1344 werror (E_CONTINUE,"current definition type ");
1345 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1349 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1350 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1354 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1355 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1359 /* compare expected agrs with actual args */
1360 exargs = csym->args ;
1361 acargs = sym->args ;
1363 /* for all the expected args do */
1366 exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1367 if ( checkType(exargs->type,acargs->type) <= 0) {
1368 werror(E_ARG_TYPE,argCnt);
1373 /* if one them ended we have a problem */
1374 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1375 (!exargs && acargs && !IS_VOID(acargs->type)))
1376 werror(E_ARG_COUNT);
1378 /* replace with this defition */
1379 sym->cdef = csym->cdef;
1380 deleteSym (SymbolTab,csym,csym->name);
1381 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1382 if (IS_EXTERN(csym->etype) && !
1383 IS_EXTERN(sym->etype)) {
1384 addSet(&publics,sym);
1389 /*-----------------------------------------------------------------*/
1390 /* processFuncArgs - does some processing with function args */
1391 /*-----------------------------------------------------------------*/
1392 void processFuncArgs (symbol *func, int ignoreName)
1398 /* if this function has variable argument list */
1399 /* then make the function a reentrant one */
1401 SPEC_RENT(func->etype) = 1;
1403 /* check if this function is defined as calleeSaves
1404 then mark it as such */
1405 func->calleeSave = inCalleeSaveList(func->name);
1407 val = func->args; /* loop thru all the arguments */
1409 /* if it is void then remove parameters */
1410 if (val && IS_VOID(val->type)) {
1415 /* reset regparm for the port */
1416 (*port->reset_regparms)();
1417 /* if any of the arguments is an aggregate */
1418 /* change it to pointer to the same type */
1420 /* mark it as a register parameter if
1421 the function does not have VA_ARG
1422 and as port dictates
1423 not inhibited by command line option or #pragma */
1424 if (!func->hasVargs &&
1425 !options.noregparms &&
1426 !IS_RENT(func->etype) &&
1427 (*port->reg_parm)(val->type)) {
1428 SPEC_REGPARM(val->etype) = 1;
1431 if ( IS_AGGREGATE(val->type)) {
1432 /* if this is a structure */
1433 /* then we need to add a new link */
1434 if (IS_STRUCT(val->type)) {
1435 /* first lets add DECLARATOR type */
1436 link *p = val->type ;
1438 werror(W_STRUCT_AS_ARG,val->name);
1439 val->type = newLink();
1440 val->type->next = p ;
1443 /* change to a pointer depending on the */
1444 /* storage class specified */
1445 switch (SPEC_SCLS(val->etype)) {
1447 DCL_TYPE(val->type) = IPOINTER;
1450 DCL_TYPE(val->type) = PPOINTER;
1456 DCL_TYPE(val->type) = POINTER ;
1459 DCL_TYPE(val->type) = CPOINTER;
1462 DCL_TYPE(val->type) = FPOINTER;
1465 DCL_TYPE(val->type) = EEPPOINTER;
1468 DCL_TYPE(val->type) = GPOINTER;
1471 /* is there is a symbol associated then */
1472 /* change the type of the symbol as well*/
1474 val->sym->type = copyLinkChain(val->type);
1475 val->sym->etype = getSpec(val->sym->type);
1483 /* if this function is reentrant or */
1484 /* automatics r 2b stacked then nothing */
1485 if (IS_RENT(func->etype) || options.stackAuto )
1492 /* if a symbolname is not given */
1493 /* synthesize a variable name */
1496 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1497 val->sym = newSymbol(val->name,1);
1498 SPEC_OCLS(val->etype) = port->mem.default_local_map;
1499 val->sym->type = copyLinkChain (val->type);
1500 val->sym->etype = getSpec (val->sym->type);
1501 val->sym->_isparm = 1;
1502 strcpy (val->sym->rname,val->name);
1503 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1504 SPEC_STAT(func->etype);
1505 addSymChain(val->sym);
1508 else /* symbol name given create synth name */ {
1510 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1511 strcpy (val->sym->rname,val->name);
1512 val->sym->_isparm = 1;
1513 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1514 (options.model ? xdata : data);
1515 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1516 SPEC_STAT(func->etype);
1522 /*-----------------------------------------------------------------*/
1523 /* isSymbolEqual - compares two symbols return 1 if they match */
1524 /*-----------------------------------------------------------------*/
1525 int isSymbolEqual (symbol *dest, symbol *src)
1527 /* if pointers match then equal */
1531 /* if one of them is null then don't match */
1535 /* if both of them have rname match on rname */
1536 if (dest->rname[0] && src->rname[0])
1537 return (!strcmp(dest->rname,src->rname));
1539 /* otherwise match on name */
1540 return (!strcmp(dest->name,src->name));
1543 /*-----------------------------------------------------------------*/
1544 /* printTypeChain - prints the type chain in human readable form */
1545 /*-----------------------------------------------------------------*/
1546 void printTypeChain (link *type, FILE *of)
1556 if (IS_DECL(type)) {
1557 switch (DCL_TYPE(type)) {
1559 fprintf (of,"function ");
1562 fprintf (of,"_generic * ");
1563 if (DCL_PTR_CONST(type))
1564 fprintf(of,"const ");
1567 fprintf (of,"_code * ");
1568 if (DCL_PTR_CONST(type))
1569 fprintf(of,"const ");
1572 fprintf (of,"_far * ");
1573 if (DCL_PTR_CONST(type))
1574 fprintf(of,"const ");
1577 fprintf (of,"_eeprom * ");
1578 if (DCL_PTR_CONST(type))
1579 fprintf(of,"const ");
1583 fprintf (of,"_near * ");
1584 if (DCL_PTR_CONST(type))
1585 fprintf(of,"const ");
1588 fprintf (of,"_idata *");
1589 if (DCL_PTR_CONST(type))
1590 fprintf(of,"const ");
1593 fprintf (of,"_pdata *");
1594 if (DCL_PTR_CONST(type))
1595 fprintf(of,"const ");
1598 fprintf (of," _unkown *");
1599 if (DCL_PTR_CONST(type))
1600 fprintf(of,"const ");
1604 fprintf (of,"array of ");
1608 if (SPEC_VOLATILE(type))
1609 fprintf (of,"volatile ");
1610 if (SPEC_USIGN(type))
1611 fprintf (of,"unsigned ");
1613 switch (SPEC_NOUN(type)) {
1616 fprintf (of,"long ");
1619 fprintf (of,"short ");
1621 fprintf (of,"int ");
1625 fprintf(of,"char ");
1629 fprintf(of,"void ");
1633 fprintf(of,"float ");
1637 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1641 fprintf(of,"sbit ");
1645 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1658 /*-----------------------------------------------------------------*/
1659 /* cdbTypeInfo - print the type information for debugger */
1660 /*-----------------------------------------------------------------*/
1661 void cdbTypeInfo (link *type,FILE *of)
1663 fprintf(of,"{%d}",getSize(type));
1665 if (IS_DECL(type)) {
1666 switch (DCL_TYPE(type)) {
1692 fprintf (of,"DA%d,",DCL_ELEM(type));
1698 switch (SPEC_NOUN(type)) {
1722 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1730 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1737 if (SPEC_USIGN(type))
1745 /*-----------------------------------------------------------------*/
1746 /* cdbSymbol - prints a symbol & its type information for debugger */
1747 /*-----------------------------------------------------------------*/
1748 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1760 fprintf(of,"S:"); /* symbol record */
1761 /* if this is not a structure symbol then
1762 we need to figure out the scope information */
1766 if (IS_STATIC(sym->etype))
1767 fprintf(of,"F%s$",moduleName); /* scope is file */
1769 fprintf(of,"G$"); /* scope is global */
1772 /* symbol is local */
1773 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1775 fprintf(of,"S$"); /* scope is structure */
1777 /* print the name, & mangled name */
1778 fprintf(of,"%s$%d$%d(",sym->name,
1779 sym->level,sym->block);
1781 cdbTypeInfo(sym->type,of);
1784 /* print the address space */
1785 map = SPEC_OCLS(sym->etype);
1786 fprintf(of,"%c,%d,%d",
1787 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1789 /* if assigned to registers then output register names */
1790 /* if this is a function then print
1791 if is it an interrupt routine & interrupt number
1792 and the register bank it is using */
1794 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1795 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1796 /* alternate location to find this symbol @ : eg registers
1803 /*-----------------------------------------------------------------*/
1804 /* cdbStruct - print a structure for debugger */
1805 /*-----------------------------------------------------------------*/
1806 void cdbStruct ( structdef *sdef,int block,FILE *of,
1807 int inStruct, char *tag)
1812 /* if block # then must have function scope */
1813 fprintf(of,"F%s$",moduleName);
1814 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1815 for (sym=sdef->fields ; sym ; sym = sym->next) {
1816 fprintf(of,"({%d}",sym->offset);
1817 cdbSymbol(sym,of,TRUE,FALSE);
1825 /*------------------------------------------------------------------*/
1826 /* cdbStructBlock - calls struct printing for a blcks */
1827 /*------------------------------------------------------------------*/
1828 void cdbStructBlock (int block , FILE *of)
1831 bucket **table = StructTab;
1835 /* go thru the entire table */
1836 for ( i = 0 ; i < 256; i++ ) {
1837 for ( chain = table[i]; chain ; chain = chain->next ) {
1838 if (chain->block >= block) {
1839 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1845 /*-----------------------------------------------------------------*/
1846 /* powof2 - returns power of two for the number if number is pow 2 */
1847 /*-----------------------------------------------------------------*/
1848 int powof2 (unsigned long num)
1854 if (num & 1) n1s++ ;
1859 if (n1s > 1 || nshifts == 0) return 0;
1860 return nshifts - 1 ;
1874 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1875 symbol *__muldiv[3][3][2];
1876 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1877 link *__multypes[3][2];
1878 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1879 symbol *__conv[2][3][2];
1883 static void _makeRegParam(symbol *sym)
1887 val = sym->args; /* loop thru all the arguments */
1889 /* reset regparm for the port */
1890 (*port->reset_regparms)();
1892 SPEC_REGPARM(val->etype) = 1;
1893 sym->argStack -= getSize(val->type);
1898 /*-----------------------------------------------------------------*/
1899 /* initCSupport - create functions for C support routines */
1900 /*-----------------------------------------------------------------*/
1901 void initCSupport ()
1903 const char *smuldivmod[] = {
1906 const char *sbwd[] = {
1907 "char", "int", "long"
1909 const char *ssu[] = {
1913 int bwd, su, muldivmod, tofrom;
1915 floatType= newFloatLink();
1917 for (bwd = 0; bwd < 3; bwd++) {
1932 __multypes[bwd][0] = l;
1933 __multypes[bwd][1] = copyLinkChain(l);
1934 SPEC_USIGN(__multypes[bwd][1]) = 1;
1937 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1938 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1939 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1940 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1941 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1942 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1943 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1944 __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1945 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1946 __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1948 for (tofrom = 0; tofrom < 2; tofrom++) {
1949 for (bwd = 0; bwd < 3; bwd++) {
1950 for (su = 0; su < 2; su++) {
1952 sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1953 __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1956 sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1957 __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
1963 for (muldivmod = 0; muldivmod < 3; muldivmod++) {
1964 for (bwd = 0; bwd < 3; bwd++) {
1965 for (su = 0; su < 2; su++) {
1966 sprintf(buffer, "_%s%s%s",
1967 smuldivmod[muldivmod],
1970 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
1971 SPEC_NONBANKED(__muldiv[muldivmod][bwd][su]->etype) = 1;
1972 if (bwd < port->muldiv.force_reg_param_below)
1973 _makeRegParam(__muldiv[muldivmod][bwd][su]);