1 /*-----------------------------------------------------------------*/
2 /* SDCCmem.c - 8051 memory management routines */
3 /*-----------------------------------------------------------------*/
8 memmap *xstack= NULL ; /* xternal stack data */
9 memmap *istack= NULL; /* internal stack */
10 memmap *code = NULL; /* code segment */
11 memmap *data = NULL; /* internal data upto 128 */
12 memmap *xdata = NULL; /* external data */
13 memmap *idata = NULL; /* internal data upto 256 */
14 memmap *bit = NULL; /* bit addressable space */
15 memmap *statsg= NULL; /* the constant data segment */
16 memmap *sfr = NULL; /* register space */
17 memmap *reg = NULL; /* register space */
18 memmap *sfrbit= NULL; /* sfr bit space */
19 memmap *generic=NULL; /* is a generic pointer */
20 memmap *overlay=NULL; /* overlay segment */
21 memmap *eeprom =NULL; /* eeprom location */
22 memmap *home =NULL; /* Unswitchable code bank */
24 /* this is a set of sets each set containing
25 symbols in a single overlay */
26 set *ovrSetSets = NULL;
29 int fatalError = 0 ;/* fatal error flag */
31 /*-----------------------------------------------------------------*/
32 /* allocMap - allocates a memory map */
33 /*-----------------------------------------------------------------*/
34 memmap *allocMap (char rspace, /* sfr space */
35 char farmap, /* far or near segment */
36 char paged , /* can this segment be paged */
37 char direct, /* directly addressable */
38 char bitaddr, /* bit addressable space*/
39 char codemap, /* this is code space */
40 unsigned sloc, /* starting location */
41 const char *name, /* 2 character name */
42 char dbName , /* debug name */
43 int ptrType /* pointer type for this space */
48 if (!(map = GC_malloc(sizeof(memmap)))) {
49 werror(E_OUT_OF_MEM,__FILE__,sizeof(memmap));
53 memset(map, ZERO, sizeof(memmap));
57 map->direct = direct ;
58 map->bitsp = bitaddr ;
59 map->codesp = codemap ;
62 map->dbName = dbName ;
63 map->ptrType= ptrType;
64 if (!(map->oFile = tempfile())) {
65 werror(E_TMPFILE_FAILED);
68 addSetHead (&tmpfileSet,map->oFile);
73 /*-----------------------------------------------------------------*/
74 /* initMem - allocates and initializes all the segments */
75 /*-----------------------------------------------------------------*/
78 /* allocate all the segments */
79 /* xternal stack segment ;
87 POINTER-TYPE - FPOINTER
89 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME,'A',PPOINTER);
91 /* internal stack segment ;
99 POINTER-TYPE - POINTER
101 istack = allocMap (0, 0, 0, 0, 0, 0,options.stack_loc, ISTACK_NAME,'B',POINTER);
111 POINTER-TYPE - CPOINTER
113 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
123 POINTER-TYPE - CPOINTER
125 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
127 /* Static segment (code for variables );
135 POINTER-TYPE - CPOINTER
137 statsg = allocMap (0, 1, 0, 0, 0, 1,0, STATIC_NAME,'D',CPOINTER);
139 /* Data segment - internal storage segment ;
147 POINTER-TYPE - POINTER
149 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
151 /* overlay segment - same as internal storage segment ;
159 POINTER-TYPE - POINTER
161 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
163 /* Xternal Data segment -
171 POINTER-TYPE - FPOINTER
173 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME,'F',FPOINTER);
175 /* Inderectly addressed internal data segment
183 POINTER-TYPE - IPOINTER
185 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,IDATA_NAME,'G',IPOINTER);
187 /* Static segment (code for variables );
195 POINTER-TYPE - _NONE_
197 bit = allocMap (0, 0, 0, 1, 1, 0,0, BIT_NAME,'H',0);
199 /* Special function register space :-
207 POINTER-TYPE - _NONE_
209 sfr = allocMap (1,0, 0, 1, 0, 0,0, REG_NAME,'I',0);
219 POINTER-TYPE - _NONE_
221 reg = allocMap (1,0, 0, 0, 0, 0, 0,REG_NAME,' ',0);
231 POINTER-TYPE - _NONE_
233 sfrbit = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J',0);
243 POINTER-TYPE - EEPPOINTER
245 eeprom = allocMap (0,1, 0, 0, 0, 0,0, REG_NAME,'K',EEPPOINTER);
247 /* the unknown map */
248 generic = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,' ',GPOINTER);
252 /*-----------------------------------------------------------------*/
253 /* allocIntoSeg - puts a symbol into a memory segment */
254 /*-----------------------------------------------------------------*/
255 void allocIntoSeg (symbol *sym)
257 memmap *segment = SPEC_OCLS(sym->etype);
258 addSet (&segment->syms,sym);
261 /*-----------------------------------------------------------------*/
262 /* allocGlobal - aassigns the output segment to a global var */
263 /*-----------------------------------------------------------------*/
264 void allocGlobal ( symbol *sym )
266 /* symbol name is internal name */
267 sprintf (sym->rname,"%s%s", port->fun_prefix, sym->name);
269 /* add it to the operandKey reset */
270 addSet(&operKeyReset,sym);
272 /* if this is a literal e.g. enumerated type */
273 /* put it in the data segment & do nothing */
274 if (IS_LITERAL(sym->etype)) {
275 SPEC_OCLS(sym->etype) = data ;
279 /* if this is a function then assign code space */
280 if (IS_FUNC(sym->type)) {
281 SPEC_OCLS(sym->etype) = code ;
282 /* if this is an interrupt service routine
283 then put it in the interrupt service array */
284 if (IS_ISR(sym->etype)) {
286 if (interrupts[SPEC_INTN(sym->etype)])
287 werror(E_INT_DEFINED,
288 SPEC_INTN(sym->etype),
289 interrupts[SPEC_INTN(sym->etype)]->name);
291 interrupts[SPEC_INTN(sym->etype)] = sym;
293 /* automagically extend the maximum interrupts */
294 if (SPEC_INTN(sym->etype) >= maxInterrupts )
295 maxInterrupts = SPEC_INTN(sym->etype) + 1;
297 /* if it is not compiler defined */
304 /* if this is a SFR or SBIT */
305 if ( SPEC_SCLS(sym->etype) == S_SFR ||
306 SPEC_SCLS(sym->etype) == S_SBIT ) {
308 /* if both absolute address & initial */
309 /* value specified then error */
310 if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
311 werror(E_SFR_INIT,sym->name);
315 SPEC_OCLS(sym->etype) =
316 (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
322 /* if this is a bit variable and no storage class */
323 if ( SPEC_NOUN(sym->etype) == V_BIT
324 && SPEC_SCLS(sym->etype) == S_BIT ) {
325 SPEC_OCLS(sym->etype) = bit ;
330 /* if bit storage class */
331 if ( SPEC_SCLS(sym->etype) == S_SBIT ) {
332 SPEC_OCLS(sym->etype) = bit;
337 /* register storage class ignored changed to FIXED */
338 if ( SPEC_SCLS(sym->etype) == S_REGISTER )
339 SPEC_SCLS(sym->etype) = S_FIXED ;
341 /* if data specified then */
342 if (SPEC_SCLS(sym->etype) == S_DATA) {
343 /* set the output class */
344 SPEC_OCLS(sym->etype) = data ;
345 /* generate the symbol */
350 /* if it is fixed, then allocate depending on the */
351 /* current memory model,same for automatics */
352 if ( SPEC_SCLS(sym->etype) == S_FIXED ||
353 SPEC_SCLS(sym->etype) == S_AUTO ) {
354 /* set the output class */
355 SPEC_OCLS(sym->etype) = port->mem.default_globl_map ;
356 /* generate the symbol */
361 /* if code change to constant */
362 if ( SPEC_SCLS(sym->etype) == S_CODE ||
363 SPEC_SCLS(sym->etype) == S_CONSTANT ) {
364 SPEC_OCLS(sym->etype) = statsg ;
369 if ( SPEC_SCLS(sym->etype) == S_XDATA ) {
370 SPEC_OCLS(sym->etype) = xdata ;
375 if ( SPEC_SCLS(sym->etype) == S_IDATA ) {
376 SPEC_OCLS(sym->etype) = idata ;
382 if ( SPEC_SCLS(sym->etype) == S_EEPROM ) {
383 SPEC_OCLS(sym->etype) = eeprom ;
391 /*-----------------------------------------------------------------*/
392 /* allocParms - parameters are always passed on stack */
393 /*-----------------------------------------------------------------*/
394 void allocParms ( value *val )
399 for ( lval = val ; lval ; lval = lval->next, pNum++ ) {
401 /* check the declaration */
402 checkDecl (lval->sym);
404 /* if this a register parm then allocate
405 it as a local variable by adding it
406 to the first block we see in the body */
407 if (IS_REGPARM(lval->etype))
410 /* mark it as my parameter */
411 lval->sym->ismyparm = 1;
412 lval->sym->localof = currFunc;
415 /* if automatic variables r 2b stacked */
416 if ( options.stackAuto || IS_RENT(currFunc->etype)) {
419 lval->sym->onStack = 1;
421 /* choose which stack 2 use */
422 /* use xternal stack */
423 if ( options.useXstack ) {
424 /* PENDING: stack direction support */
425 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xstack ;
426 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
427 xstackPtr - getSize(lval->type);
428 xstackPtr -= getSize (lval->type);
430 else { /* use internal stack */
431 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = istack ;
432 if (port->stack.direction > 0) {
433 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
434 stackPtr - ( SPEC_BANK(currFunc->etype) ? port->stack.bank_overhead : 0) -
435 getSize(lval->type) -
436 (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0);
437 stackPtr -= getSize (lval->type);
440 /* This looks like the wrong order but it turns out OK... */
441 /* PENDING: isr, bank overhead, ... */
442 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
444 (IS_BANKEDCALL(currFunc->etype) ? port->stack.banked_overhead : 0) +
445 (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0) +
447 stackPtr += getSize (lval->type);
450 allocIntoSeg(lval->sym);
452 else { /* allocate them in the automatic space */
453 /* generate a unique name */
454 sprintf (lval->sym->rname,"%s%s_PARM_%d", port->fun_prefix, currFunc->name,pNum);
455 strcpy (lval->name,lval->sym->rname);
457 /* if declared in external storage */
458 if (SPEC_SCLS(lval->etype) == S_XDATA)
459 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
461 /* other wise depending on the memory model
462 note here that we put it into the overlay segment
463 first, we will remove it from the overlay segment
464 after the overlay determination has been done */
465 if (options.model == MODEL_SMALL) {
466 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) =
467 ( options.model == MODEL_SMALL ? port->mem.default_local_map :
468 (options.noOverlay ? port->mem.default_local_map
471 SPEC_SCLS(lval->etype) = S_XDATA;
472 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
474 allocIntoSeg(lval->sym);
481 /*-----------------------------------------------------------------*/
482 /* deallocParms - parameters are always passed on stack */
483 /*-----------------------------------------------------------------*/
484 void deallocParms ( value *val )
488 for ( lval = val ; lval ; lval = lval->next ) {
490 /* unmark is myparm */
491 lval->sym->ismyparm = 0;
492 /* if on stack then depending on which stack */
494 /* delete it from the symbol table */
495 deleteSym (SymbolTab,lval->sym,lval->sym->name);
497 if (!lval->sym->isref) {
498 lval->sym->allocreq = 1;
499 werror(W_NO_REFERENCE,currFunc->name,
500 "function argument",lval->sym->name);
503 /* move the rname if any to the name for both val & sym */
504 /* and leave a copy of it in the symbol table */
505 if (lval->sym->rname[0]) {
506 char buffer[SDCC_NAME_MAX];
507 strcpy(buffer,lval->sym->rname);
508 lval->sym = copySymbol(lval->sym);
509 strcpy(lval->sym->rname,buffer);
510 strcpy(lval->name,strcpy(lval->sym->name,lval->sym->rname));
511 addSym (SymbolTab, lval->sym, lval->sym->name,
512 lval->sym->level,lval->sym->block);
513 lval->sym->_isparm = 1;
514 addSet(&operKeyReset,lval->sym);
522 /*-----------------------------------------------------------------*/
523 /* allocLocal - allocate local variables */
524 /*-----------------------------------------------------------------*/
525 void allocLocal ( symbol *sym )
528 /* generate an unique name */
529 sprintf(sym->rname,"%s%s_%s_%d_%d",
531 currFunc->name,sym->name,sym->level,sym->block);
534 sym->localof = currFunc;
536 /* if this is a static variable */
537 if ( IS_STATIC (sym->etype)) {
538 SPEC_OCLS(sym->etype) = port->mem.default_local_map;
544 /* if volatile then */
545 if (IS_VOLATILE(sym->etype))
548 /* this is automatic */
550 /* if it to be placed on the stack */
551 if ( options.stackAuto || reentrant) {
554 if ( options.useXstack ) {
555 /* PENDING: stack direction for xstack */
556 SPEC_OCLS(sym->etype) = xstack ;
557 SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1);
558 xstackPtr += getSize (sym->type) ;
561 SPEC_OCLS(sym->etype) = istack ;
562 if (port->stack.direction > 0) {
563 SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1);
564 stackPtr += getSize (sym->type) ;
567 stackPtr -= getSize (sym->type);
568 SPEC_STAK(sym->etype) = sym->stack = stackPtr;
575 /* else depending on the storage class specified */
576 if ( SPEC_SCLS(sym->etype) == S_XDATA ) {
577 SPEC_OCLS(sym->etype) = xdata ;
582 if ( (SPEC_SCLS(sym->etype) == S_CODE ||
583 SPEC_SCLS(sym->etype) == S_CONSTANT) &&
585 SPEC_OCLS(sym->etype) = statsg ;
590 if ( SPEC_SCLS(sym->etype) == S_IDATA ) {
591 SPEC_OCLS(sym->etype) = idata ;
597 /* if this is a function then assign code space */
598 if (IS_FUNC(sym->type)) {
599 SPEC_OCLS(sym->etype) = code ;
603 /* if this is a SFR or SBIT */
604 if ( SPEC_SCLS(sym->etype) == S_SFR ||
605 SPEC_SCLS(sym->etype) == S_SBIT ) {
607 /* if both absolute address & initial */
608 /* value specified then error */
609 if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
610 werror(E_SFR_INIT,sym->name);
614 SPEC_OCLS(sym->etype) =
615 (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
621 /* if this is a bit variable and no storage class */
622 if ( SPEC_NOUN(sym->etype) == V_BIT
623 && (SPEC_SCLS(sym->etype) == S_BIT)) {
624 SPEC_OCLS(sym->etype) = bit ;
629 if ( SPEC_SCLS(sym->etype) == S_DATA ) {
630 SPEC_OCLS(sym->etype) = (options.noOverlay ? data : overlay );
635 if ( SPEC_SCLS(sym->etype) == S_EEPROM ) {
636 SPEC_OCLS(sym->etype) = eeprom;
641 /* again note that we have put it into the overlay segment
642 will remove and put into the 'data' segment if required after
643 overlay analysis has been done */
644 SPEC_OCLS(sym->etype) = ( options.model == MODEL_SMALL ? port->mem.default_local_map :
645 (options.noOverlay ? port->mem.default_local_map
650 /*-----------------------------------------------------------------*/
651 /* deallocLocal - deallocates the local variables */
652 /*-----------------------------------------------------------------*/
653 void deallocLocal ( symbol *csym )
657 for ( sym = csym ; sym ; sym = sym->next) {
661 /* if it is on the stack */
663 if (options.useXstack)
664 xstackPtr -= getSize(sym->type);
666 stackPtr -= getSize(sym->type);
668 /* if not used give a warning */
669 if (!sym->isref && !IS_STATIC(sym->etype))
670 werror(W_NO_REFERENCE,currFunc->name,
671 "local variable",sym->name);
672 /* now delete it from the symbol table */
673 deleteSym (SymbolTab,sym,sym->name);
677 /*-----------------------------------------------------------------*/
678 /* overlay2data - moves declarations from the overlay seg to data */
679 /*-----------------------------------------------------------------*/
684 for (sym = setFirstItem(overlay->syms); sym;
685 sym = setNextItem(overlay->syms)) {
687 SPEC_OCLS(sym->etype) = data;
691 setToNull((void **) &overlay->syms);
695 /*-----------------------------------------------------------------*/
696 /* overlay2Set - will add all symbols from the overlay segment to */
697 /* the set of sets containing the overlable symbols */
698 /*-----------------------------------------------------------------*/
704 for (sym = setFirstItem(overlay->syms); sym;
705 sym = setNextItem(overlay->syms)) {
710 setToNull((void **) &overlay->syms);
711 addSet (&ovrSetSets,oset);
715 /*-----------------------------------------------------------------*/
716 /* allocVariables - creates decl & assign storage class for a v */
717 /*-----------------------------------------------------------------*/
718 int allocVariables ( symbol *symChain )
725 /* go thru the symbol chain */
726 for ( sym = symChain ; sym ; sym = sym->next ) {
728 /* if this is a typedef then add it */
729 /* to the typedef table */
730 if (IS_TYPEDEF(sym->etype)) {
731 /* check if the typedef already exists */
732 csym = findSym (TypedefTab, NULL, sym->name );
733 if ( csym && csym->level == sym->level )
734 werror(E_DUPLICATE_TYPEDEF,sym->name);
736 addSym (TypedefTab, sym , sym->name,sym->level,sym->block);
737 continue ; /* go to the next one */
739 /* make sure it already exist */
740 csym = findSymWithLevel (SymbolTab, sym);
741 if (! csym || (csym && csym->level != sym->level) )
744 /* check the declaration */
747 /* if this is a function or a pointer to function */
748 /* then args processing */
749 if (funcInChain(csym->type)) {
751 processFuncArgs (csym, 1);
752 /* if register bank specified then update maxRegBank */
753 if (maxRegBank < SPEC_BANK(csym->etype))
754 maxRegBank = SPEC_BANK(csym->etype);
757 /* if this is a extern variable then change the */
758 /* level to zero temporarily */
759 if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) {
760 saveLevel = csym->level ;
764 /* if this is a literal then it is an enumerated */
765 /* type so need not allocate it space for it */
766 if (IS_LITERAL(sym->etype))
769 /* generate the actual declaration */
773 stack += getSize(csym->type) ;
778 /* restore the level */
779 if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type))
780 csym->level = saveLevel;
786 /*-----------------------------------------------------------------*/
787 /* redoStackOffsets :- will reassign the values for stack offsets */
788 /*-----------------------------------------------------------------*/
789 void redoStackOffsets ()
795 /* after register allocation is complete we know
796 which variables will need to be assigned space
797 on the stack. We will eliminate those variables
798 which do not have the allocReq flag thus reducing
800 for ( sym = setFirstItem(istack->syms); sym;
801 sym = setNextItem(istack->syms)) {
803 int size = getSize(sym->type);
804 /* nothing to do with parameters so continue */
805 if ((sym->_isparm && !IS_REGPARM(sym->etype)))
808 if ( IS_AGGREGATE(sym->type)) {
809 if (port->stack.direction > 0) {
810 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
815 SPEC_STAK(sym->etype) = sym->stack = sPtr;
820 /* if allocation not required then subtract
821 size from overall stack size & continue */
822 if (!sym->allocreq) {
823 currFunc->stack -= size;
824 SPEC_STAK(currFunc->etype) -= size;
828 if (port->stack.direction > 0) {
829 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
834 SPEC_STAK(sym->etype) = sym->stack = sPtr;
838 /* do the same for the external stack */
840 for ( sym = setFirstItem(xstack->syms); sym;
841 sym = setNextItem(xstack->syms)) {
843 int size = getSize(sym->type);
844 /* nothing to do with parameters so continue */
845 if ((sym->_isparm && !IS_REGPARM(sym->etype)))
848 if (IS_AGGREGATE(sym->type)) {
849 SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
854 /* if allocation not required then subtract
855 size from overall stack size & continue */
856 if (!sym->allocreq) {
857 currFunc->xstack -= size;
858 SPEC_STAK(currFunc->etype) -= size;
862 SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
866 /* if the debug option is set then output the
867 symbols to the map file */
868 if (options.debug && !options.nodebug) {
869 for (sym = setFirstItem(istack->syms); sym;
870 sym = setNextItem(istack->syms))
871 cdbSymbol(sym,cdbFile,FALSE,FALSE);
873 for (sym = setFirstItem(xstack->syms); sym;
874 sym = setNextItem(xstack->syms))
875 cdbSymbol(sym,cdbFile,FALSE,FALSE);
879 /*-----------------------------------------------------------------*/
880 /* printAllocInfoSeg- print the allocation for a given section */
881 /*-----------------------------------------------------------------*/
882 static void printAllocInfoSeg ( memmap *map, symbol *func, FILE *of)
887 if (!map->syms) return;
889 for (sym = setFirstItem(map->syms); sym;
890 sym = setNextItem(map->syms)) {
892 if (sym->level == 0) continue;
893 if (sym->localof != func) continue ;
894 fprintf(of,";%-25s Allocated to ",sym->name);
896 /* if assigned to registers */
897 if (!sym->allocreq && sym->reqv) {
899 sym = OP_SYMBOL(sym->reqv);
900 fprintf(of,"registers ");
901 for (i = 0 ; i < 4 && sym->regs[i] ; i++)
902 fprintf(of,"%s ",port->getRegName(sym->regs[i]));
909 fprintf(of,"stack - offset %d\n",sym->stack);
913 /* otherwise give rname */
914 fprintf(of,"in memory with name '%s'\n",sym->rname);
918 /*-----------------------------------------------------------------*/
919 /* canOverlayLocals - returns true if the local variables can overlayed */
920 /*-----------------------------------------------------------------*/
921 static bool canOverlayLocals (eBBlock **ebbs, int count)
924 /* if staticAuto is in effect or the current function
925 being compiled is reentrant or the overlay segment
926 is empty or no overlay option is in effect then */
927 if (options.noOverlay ||
930 (IS_RENT(currFunc->etype) ||
931 IS_ISR(currFunc->etype))) ||
932 elementsInSet(overlay->syms) == 0)
936 /* otherwise do thru the blocks and see if there
937 any function calls if found then return false */
938 for (i = 0; i < count ; i++ ) {
941 for (ic = ebbs[i]->sch; ic ; ic = ic->next)
942 if (ic && ( ic->op == CALL || ic->op == PCALL))
946 /* no function calls found return TRUE */
950 /*-----------------------------------------------------------------*/
951 /* doOverlays - move the overlay segment to appropriate location */
952 /*-----------------------------------------------------------------*/
953 void doOverlays( eBBlock **ebbs, int count)
955 /* check if the parameters and local variables
956 of this function can be put in the overlay segment
957 This check is essentially to see if the function
958 calls any other functions if yes then we cannot
960 if (canOverlayLocals(ebbs,count))
961 /* if we can then put the parameters &
962 local variables in the overlay set */
965 /* otherwise put them into data where
970 /*-----------------------------------------------------------------*/
971 /* printAllocInfo - prints allocation information for a function */
972 /*-----------------------------------------------------------------*/
973 void printAllocInfo( symbol * func, FILE *of)
975 if (!of) of = stdout;
977 /* must be called after register allocation is complete */
978 fprintf(of,";------------------------------------------------------------\n");
979 fprintf(of,";Allocation info for local variables in function '%s'\n",func->name);
980 fprintf(of,";------------------------------------------------------------\n");
982 printAllocInfoSeg(xstack,func,of);
983 printAllocInfoSeg(istack,func,of);
984 printAllocInfoSeg(code,func,of);
985 printAllocInfoSeg(data,func,of);
986 printAllocInfoSeg(xdata,func,of);
987 printAllocInfoSeg(idata,func,of);
988 printAllocInfoSeg(sfr,func,of);
989 printAllocInfoSeg(sfrbit,func,of);