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;
28 extern set *operKeyReset ;
29 extern set *tmpfileSet ;
30 extern symbol *interrupts[];
32 int fatalError = 0 ;/* fatal error flag */
34 /*-----------------------------------------------------------------*/
35 /* allocMap - allocates a memory map */
36 /*-----------------------------------------------------------------*/
37 memmap *allocMap (char rspace, /* sfr space */
38 char farmap, /* far or near segment */
39 char paged , /* can this segment be paged */
40 char direct, /* directly addressable */
41 char bitaddr, /* bit addressable space*/
42 char codemap, /* this is code space */
43 unsigned sloc, /* starting location */
44 const char *name, /* 2 character name */
45 char dbName , /* debug name */
46 int ptrType /* pointer type for this space */
51 if (!(map = GC_malloc(sizeof(memmap)))) {
52 werror(E_OUT_OF_MEM,__FILE__,sizeof(memmap));
56 memset(map, ZERO, sizeof(memmap));
60 map->direct = direct ;
61 map->bitsp = bitaddr ;
62 map->codesp = codemap ;
65 map->dbName = dbName ;
66 map->ptrType= ptrType;
67 if (!(map->oFile = tempfile())) {
68 werror(E_TMPFILE_FAILED);
71 addSetHead (&tmpfileSet,map->oFile);
76 /*-----------------------------------------------------------------*/
77 /* initMem - allocates and initializes all the segments */
78 /*-----------------------------------------------------------------*/
81 /* allocate all the segments */
82 /* xternal stack segment ;
90 POINTER-TYPE - FPOINTER
92 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME,'A',PPOINTER);
94 /* internal stack segment ;
102 POINTER-TYPE - POINTER
104 istack = allocMap (0, 0, 0, 0, 0, 0,options.stack_loc, ISTACK_NAME,'B',POINTER);
114 POINTER-TYPE - CPOINTER
116 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
126 POINTER-TYPE - CPOINTER
128 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER);
130 /* Static segment (code for variables );
138 POINTER-TYPE - CPOINTER
140 statsg = allocMap (0, 1, 0, 0, 0, 1,0, STATIC_NAME,'D',CPOINTER);
142 /* Data segment - internal storage segment ;
150 POINTER-TYPE - POINTER
152 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
154 /* overlay segment - same as internal storage segment ;
162 POINTER-TYPE - POINTER
164 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER);
166 /* Xternal Data segment -
174 POINTER-TYPE - FPOINTER
176 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME,'F',FPOINTER);
178 /* Inderectly addressed internal data segment
186 POINTER-TYPE - IPOINTER
188 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,IDATA_NAME,'G',IPOINTER);
190 /* Static segment (code for variables );
198 POINTER-TYPE - _NONE_
200 bit = allocMap (0, 0, 0, 1, 1, 0,0, BIT_NAME,'H',0);
202 /* Special function register space :-
210 POINTER-TYPE - _NONE_
212 sfr = allocMap (1,0, 0, 1, 0, 0,0, REG_NAME,'I',0);
222 POINTER-TYPE - _NONE_
224 reg = allocMap (1,0, 0, 0, 0, 0, 0,REG_NAME,' ',0);
234 POINTER-TYPE - _NONE_
236 sfrbit = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J',0);
246 POINTER-TYPE - EEPPOINTER
248 eeprom = allocMap (0,1, 0, 0, 0, 0,0, REG_NAME,'K',EEPPOINTER);
250 /* the unknown map */
251 generic = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,' ',GPOINTER);
255 /*-----------------------------------------------------------------*/
256 /* allocIntoSeg - puts a symbol into a memory segment */
257 /*-----------------------------------------------------------------*/
258 void allocIntoSeg (symbol *sym)
260 memmap *segment = SPEC_OCLS(sym->etype);
261 addSet (&segment->syms,sym);
264 /*-----------------------------------------------------------------*/
265 /* allocGlobal - aassigns the output segment to a global var */
266 /*-----------------------------------------------------------------*/
267 void allocGlobal ( symbol *sym )
269 /* symbol name is internal name */
270 sprintf (sym->rname,"%s%s", port->fun_prefix, sym->name);
272 /* add it to the operandKey reset */
273 addSet(&operKeyReset,sym);
275 /* if this is a literal e.g. enumerated type */
276 /* put it in the data segment & do nothing */
277 if (IS_LITERAL(sym->etype)) {
278 SPEC_OCLS(sym->etype) = data ;
282 /* if this is a function then assign code space */
283 if (IS_FUNC(sym->type)) {
284 SPEC_OCLS(sym->etype) = code ;
285 /* if this is an interrupt service routine
286 then put it in the interrupt service array */
287 if (IS_ISR(sym->etype)) {
289 if (interrupts[SPEC_INTN(sym->etype)])
290 werror(E_INT_DEFINED,
291 SPEC_INTN(sym->etype),
292 interrupts[SPEC_INTN(sym->etype)]->name);
294 interrupts[SPEC_INTN(sym->etype)] = sym;
296 /* automagically extend the maximum interrupts */
297 if (SPEC_INTN(sym->etype) >= maxInterrupts )
298 maxInterrupts = SPEC_INTN(sym->etype) + 1;
300 /* if it is not compiler defined */
307 /* if this is a SFR or SBIT */
308 if ( SPEC_SCLS(sym->etype) == S_SFR ||
309 SPEC_SCLS(sym->etype) == S_SBIT ) {
311 /* if both absolute address & initial */
312 /* value specified then error */
313 if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
314 werror(E_SFR_INIT,sym->name);
318 SPEC_OCLS(sym->etype) =
319 (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
325 /* if this is a bit variable and no storage class */
326 if ( SPEC_NOUN(sym->etype) == V_BIT
327 && SPEC_SCLS(sym->etype) == S_BIT ) {
328 SPEC_OCLS(sym->etype) = bit ;
333 /* if bit storage class */
334 if ( SPEC_SCLS(sym->etype) == S_SBIT ) {
335 SPEC_OCLS(sym->etype) = bit;
340 /* register storage class ignored changed to FIXED */
341 if ( SPEC_SCLS(sym->etype) == S_REGISTER )
342 SPEC_SCLS(sym->etype) = S_FIXED ;
344 /* if data specified then */
345 if (SPEC_SCLS(sym->etype) == S_DATA) {
346 /* set the output class */
347 SPEC_OCLS(sym->etype) = data ;
348 /* generate the symbol */
353 /* if it is fixed, then allocate depending on the */
354 /* current memory model,same for automatics */
355 if ( SPEC_SCLS(sym->etype) == S_FIXED ||
356 SPEC_SCLS(sym->etype) == S_AUTO ) {
357 /* set the output class */
358 SPEC_OCLS(sym->etype) = port->mem.default_globl_map ;
359 /* generate the symbol */
364 /* if code change to constant */
365 if ( SPEC_SCLS(sym->etype) == S_CODE ||
366 SPEC_SCLS(sym->etype) == S_CONSTANT ) {
367 SPEC_OCLS(sym->etype) = statsg ;
372 if ( SPEC_SCLS(sym->etype) == S_XDATA ) {
373 SPEC_OCLS(sym->etype) = xdata ;
378 if ( SPEC_SCLS(sym->etype) == S_IDATA ) {
379 SPEC_OCLS(sym->etype) = idata ;
385 if ( SPEC_SCLS(sym->etype) == S_EEPROM ) {
386 SPEC_OCLS(sym->etype) = eeprom ;
394 /*-----------------------------------------------------------------*/
395 /* allocParms - parameters are always passed on stack */
396 /*-----------------------------------------------------------------*/
397 void allocParms ( value *val )
402 for ( lval = val ; lval ; lval = lval->next, pNum++ ) {
404 /* check the declaration */
405 checkDecl (lval->sym);
407 /* if this a register parm then allocate
408 it as a local variable by adding it
409 to the first block we see in the body */
410 if (IS_REGPARM(lval->etype))
413 /* mark it as my parameter */
414 lval->sym->ismyparm = 1;
415 lval->sym->localof = currFunc;
418 /* if automatic variables r 2b stacked */
419 if ( options.stackAuto || IS_RENT(currFunc->etype)) {
422 lval->sym->onStack = 1;
424 /* choose which stack 2 use */
425 /* use xternal stack */
426 if ( options.useXstack ) {
427 /* PENDING: stack direction support */
428 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xstack ;
429 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
430 xstackPtr - getSize(lval->type);
431 xstackPtr -= getSize (lval->type);
433 else { /* use internal stack */
434 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = istack ;
435 if (port->stack.direction > 0) {
436 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
437 stackPtr - ( SPEC_BANK(currFunc->etype) ? port->stack.bank_overhead : 0) -
438 getSize(lval->type) -
439 (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0);
440 stackPtr -= getSize (lval->type);
443 /* This looks like the wrong order but it turns out OK... */
444 /* PENDING: isr, bank overhead, ... */
445 SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack =
447 (IS_BANKEDCALL(currFunc->etype) ? port->stack.banked_overhead : 0) +
448 (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0) +
450 stackPtr += getSize (lval->type);
453 allocIntoSeg(lval->sym);
455 else { /* allocate them in the automatic space */
456 /* generate a unique name */
457 sprintf (lval->sym->rname,"%s%s_PARM_%d", port->fun_prefix, currFunc->name,pNum);
458 strcpy (lval->name,lval->sym->rname);
460 /* if declared in external storage */
461 if (SPEC_SCLS(lval->etype) == S_XDATA)
462 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
464 /* other wise depending on the memory model
465 note here that we put it into the overlay segment
466 first, we will remove it from the overlay segment
467 after the overlay determination has been done */
468 if (options.model == MODEL_SMALL) {
469 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) =
470 ( options.model == MODEL_SMALL ? port->mem.default_local_map :
471 (options.noOverlay ? port->mem.default_local_map
474 SPEC_SCLS(lval->etype) = S_XDATA;
475 SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata;
477 allocIntoSeg(lval->sym);
484 /*-----------------------------------------------------------------*/
485 /* deallocParms - parameters are always passed on stack */
486 /*-----------------------------------------------------------------*/
487 void deallocParms ( value *val )
491 for ( lval = val ; lval ; lval = lval->next ) {
493 /* unmark is myparm */
494 lval->sym->ismyparm = 0;
495 /* if on stack then depending on which stack */
497 /* delete it from the symbol table */
498 deleteSym (SymbolTab,lval->sym,lval->sym->name);
500 if (!lval->sym->isref) {
501 lval->sym->allocreq = 1;
502 werror(W_NO_REFERENCE,currFunc->name,
503 "function argument",lval->sym->name);
506 /* move the rname if any to the name for both val & sym */
507 /* and leave a copy of it in the symbol table */
508 if (lval->sym->rname[0]) {
509 char buffer[SDCC_NAME_MAX];
510 strcpy(buffer,lval->sym->rname);
511 lval->sym = copySymbol(lval->sym);
512 strcpy(lval->sym->rname,buffer);
513 strcpy(lval->name,strcpy(lval->sym->name,lval->sym->rname));
514 addSym (SymbolTab, lval->sym, lval->sym->name,
515 lval->sym->level,lval->sym->block);
516 lval->sym->_isparm = 1;
517 addSet(&operKeyReset,lval->sym);
525 /*-----------------------------------------------------------------*/
526 /* allocLocal - allocate local variables */
527 /*-----------------------------------------------------------------*/
528 void allocLocal ( symbol *sym )
531 /* generate an unique name */
532 sprintf(sym->rname,"%s%s_%s_%d_%d",
534 currFunc->name,sym->name,sym->level,sym->block);
537 sym->localof = currFunc;
539 /* if this is a static variable */
540 if ( IS_STATIC (sym->etype)) {
541 SPEC_OCLS(sym->etype) = port->mem.default_local_map;
547 /* if volatile then */
548 if (IS_VOLATILE(sym->etype))
551 /* this is automatic */
553 /* if it to be placed on the stack */
554 if ( options.stackAuto || reentrant) {
557 if ( options.useXstack ) {
558 /* PENDING: stack direction for xstack */
559 SPEC_OCLS(sym->etype) = xstack ;
560 SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1);
561 xstackPtr += getSize (sym->type) ;
564 SPEC_OCLS(sym->etype) = istack ;
565 if (port->stack.direction > 0) {
566 SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1);
567 stackPtr += getSize (sym->type) ;
570 stackPtr -= getSize (sym->type);
571 SPEC_STAK(sym->etype) = sym->stack = stackPtr;
578 /* else depending on the storage class specified */
579 if ( SPEC_SCLS(sym->etype) == S_XDATA ) {
580 SPEC_OCLS(sym->etype) = xdata ;
585 if ( (SPEC_SCLS(sym->etype) == S_CODE ||
586 SPEC_SCLS(sym->etype) == S_CONSTANT) &&
588 SPEC_OCLS(sym->etype) = statsg ;
593 if ( SPEC_SCLS(sym->etype) == S_IDATA ) {
594 SPEC_OCLS(sym->etype) = idata ;
600 /* if this is a function then assign code space */
601 if (IS_FUNC(sym->type)) {
602 SPEC_OCLS(sym->etype) = code ;
606 /* if this is a SFR or SBIT */
607 if ( SPEC_SCLS(sym->etype) == S_SFR ||
608 SPEC_SCLS(sym->etype) == S_SBIT ) {
610 /* if both absolute address & initial */
611 /* value specified then error */
612 if ( IS_ABSOLUTE (sym->etype) && sym->ival ) {
613 werror(E_SFR_INIT,sym->name);
617 SPEC_OCLS(sym->etype) =
618 (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit);
624 /* if this is a bit variable and no storage class */
625 if ( SPEC_NOUN(sym->etype) == V_BIT
626 && (SPEC_SCLS(sym->etype) == S_BIT)) {
627 SPEC_OCLS(sym->etype) = bit ;
632 if ( SPEC_SCLS(sym->etype) == S_DATA ) {
633 SPEC_OCLS(sym->etype) = (options.noOverlay ? data : overlay );
638 if ( SPEC_SCLS(sym->etype) == S_EEPROM ) {
639 SPEC_OCLS(sym->etype) = eeprom;
644 /* again note that we have put it into the overlay segment
645 will remove and put into the 'data' segment if required after
646 overlay analysis has been done */
647 SPEC_OCLS(sym->etype) = ( options.model == MODEL_SMALL ? port->mem.default_local_map :
648 (options.noOverlay ? port->mem.default_local_map
653 /*-----------------------------------------------------------------*/
654 /* deallocLocal - deallocates the local variables */
655 /*-----------------------------------------------------------------*/
656 void deallocLocal ( symbol *csym )
660 for ( sym = csym ; sym ; sym = sym->next) {
664 /* if it is on the stack */
666 if (options.useXstack)
667 xstackPtr -= getSize(sym->type);
669 stackPtr -= getSize(sym->type);
671 /* if not used give a warning */
672 if (!sym->isref && !IS_STATIC(sym->etype))
673 werror(W_NO_REFERENCE,currFunc->name,
674 "local variable",sym->name);
675 /* now delete it from the symbol table */
676 deleteSym (SymbolTab,sym,sym->name);
680 /*-----------------------------------------------------------------*/
681 /* overlay2data - moves declarations from the overlay seg to data */
682 /*-----------------------------------------------------------------*/
687 for (sym = setFirstItem(overlay->syms); sym;
688 sym = setNextItem(overlay->syms)) {
690 SPEC_OCLS(sym->etype) = data;
694 setToNull((void **) &overlay->syms);
698 /*-----------------------------------------------------------------*/
699 /* overlay2Set - will add all symbols from the overlay segment to */
700 /* the set of sets containing the overlable symbols */
701 /*-----------------------------------------------------------------*/
707 for (sym = setFirstItem(overlay->syms); sym;
708 sym = setNextItem(overlay->syms)) {
713 setToNull((void **) &overlay->syms);
714 addSet (&ovrSetSets,oset);
718 /*-----------------------------------------------------------------*/
719 /* allocVariables - creates decl & assign storage class for a v */
720 /*-----------------------------------------------------------------*/
721 int allocVariables ( symbol *symChain )
728 /* go thru the symbol chain */
729 for ( sym = symChain ; sym ; sym = sym->next ) {
731 /* if this is a typedef then add it */
732 /* to the typedef table */
733 if (IS_TYPEDEF(sym->etype)) {
734 /* check if the typedef already exists */
735 csym = findSym (TypedefTab, NULL, sym->name );
736 if ( csym && csym->level == sym->level )
737 werror(E_DUPLICATE_TYPEDEF,sym->name);
739 addSym (TypedefTab, sym , sym->name,sym->level,sym->block);
740 continue ; /* go to the next one */
742 /* make sure it already exist */
743 csym = findSymWithLevel (SymbolTab, sym);
744 if (! csym || (csym && csym->level != sym->level) )
747 /* check the declaration */
750 /* if this is a function or a pointer to function */
751 /* then args processing */
752 if (funcInChain(csym->type)) {
754 processFuncArgs (csym, 1);
755 /* if register bank specified then update maxRegBank */
756 if (maxRegBank < SPEC_BANK(csym->etype))
757 maxRegBank = SPEC_BANK(csym->etype);
760 /* if this is a extern variable then change the */
761 /* level to zero temporarily */
762 if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) {
763 saveLevel = csym->level ;
767 /* if this is a literal then it is an enumerated */
768 /* type so need not allocate it space for it */
769 if (IS_LITERAL(sym->etype))
772 /* generate the actual declaration */
776 stack += getSize(csym->type) ;
781 /* restore the level */
782 if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type))
783 csym->level = saveLevel;
789 /*-----------------------------------------------------------------*/
790 /* redoStackOffsets :- will reassign the values for stack offsets */
791 /*-----------------------------------------------------------------*/
792 void redoStackOffsets ()
798 /* after register allocation is complete we know
799 which variables will need to be assigned space
800 on the stack. We will eliminate those variables
801 which do not have the allocReq flag thus reducing
803 for ( sym = setFirstItem(istack->syms); sym;
804 sym = setNextItem(istack->syms)) {
806 int size = getSize(sym->type);
807 /* nothing to do with parameters so continue */
808 if ((sym->_isparm && !IS_REGPARM(sym->etype)))
811 if ( IS_AGGREGATE(sym->type)) {
812 if (port->stack.direction > 0) {
813 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
818 SPEC_STAK(sym->etype) = sym->stack = sPtr;
823 /* if allocation not required then subtract
824 size from overall stack size & continue */
825 if (!sym->allocreq) {
826 currFunc->stack -= size;
827 SPEC_STAK(currFunc->etype) -= size;
831 if (port->stack.direction > 0) {
832 SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1);
837 SPEC_STAK(sym->etype) = sym->stack = sPtr;
841 /* do the same for the external stack */
843 for ( sym = setFirstItem(xstack->syms); sym;
844 sym = setNextItem(xstack->syms)) {
846 int size = getSize(sym->type);
847 /* nothing to do with parameters so continue */
848 if ((sym->_isparm && !IS_REGPARM(sym->etype)))
851 if (IS_AGGREGATE(sym->type)) {
852 SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
857 /* if allocation not required then subtract
858 size from overall stack size & continue */
859 if (!sym->allocreq) {
860 currFunc->xstack -= size;
861 SPEC_STAK(currFunc->etype) -= size;
865 SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1);
869 /* if the debug option is set then output the
870 symbols to the map file */
871 if (options.debug && !options.nodebug) {
872 for (sym = setFirstItem(istack->syms); sym;
873 sym = setNextItem(istack->syms))
874 cdbSymbol(sym,cdbFile,FALSE,FALSE);
876 for (sym = setFirstItem(xstack->syms); sym;
877 sym = setNextItem(xstack->syms))
878 cdbSymbol(sym,cdbFile,FALSE,FALSE);
882 /*-----------------------------------------------------------------*/
883 /* printAllocInfoSeg- print the allocation for a given section */
884 /*-----------------------------------------------------------------*/
885 static void printAllocInfoSeg ( memmap *map, symbol *func, FILE *of)
890 if (!map->syms) return;
892 for (sym = setFirstItem(map->syms); sym;
893 sym = setNextItem(map->syms)) {
895 if (sym->level == 0) continue;
896 if (sym->localof != func) continue ;
897 fprintf(of,";%-25s Allocated to ",sym->name);
899 /* if assigned to registers */
900 if (!sym->allocreq && sym->reqv) {
902 sym = OP_SYMBOL(sym->reqv);
903 fprintf(of,"registers ");
904 for (i = 0 ; i < 4 && sym->regs[i] ; i++)
905 fprintf(of,"%s ",port->getRegName(sym->regs[i]));
912 fprintf(of,"stack - offset %d\n",sym->stack);
916 /* otherwise give rname */
917 fprintf(of,"in memory with name '%s'\n",sym->rname);
921 /*-----------------------------------------------------------------*/
922 /* canOverlayLocals - returns true if the local variables can overlayed */
923 /*-----------------------------------------------------------------*/
924 static bool canOverlayLocals (eBBlock **ebbs, int count)
927 /* if staticAuto is in effect or the current function
928 being compiled is reentrant or the overlay segment
929 is empty or no overlay option is in effect then */
930 if (options.noOverlay ||
933 (IS_RENT(currFunc->etype) ||
934 IS_ISR(currFunc->etype))) ||
935 elementsInSet(overlay->syms) == 0)
939 /* otherwise do thru the blocks and see if there
940 any function calls if found then return false */
941 for (i = 0; i < count ; i++ ) {
944 for (ic = ebbs[i]->sch; ic ; ic = ic->next)
945 if (ic && ( ic->op == CALL || ic->op == PCALL))
949 /* no function calls found return TRUE */
953 /*-----------------------------------------------------------------*/
954 /* doOverlays - move the overlay segment to appropriate location */
955 /*-----------------------------------------------------------------*/
956 void doOverlays( eBBlock **ebbs, int count)
958 /* check if the parameters and local variables
959 of this function can be put in the overlay segment
960 This check is essentially to see if the function
961 calls any other functions if yes then we cannot
963 if (canOverlayLocals(ebbs,count))
964 /* if we can then put the parameters &
965 local variables in the overlay set */
968 /* otherwise put them into data where
973 /*-----------------------------------------------------------------*/
974 /* printAllocInfo - prints allocation information for a function */
975 /*-----------------------------------------------------------------*/
976 void printAllocInfo( symbol * func, FILE *of)
978 if (!of) of = stdout;
980 /* must be called after register allocation is complete */
981 fprintf(of,";------------------------------------------------------------\n");
982 fprintf(of,";Allocation info for local variables in function '%s'\n",func->name);
983 fprintf(of,";------------------------------------------------------------\n");
985 printAllocInfoSeg(xstack,func,of);
986 printAllocInfoSeg(istack,func,of);
987 printAllocInfoSeg(code,func,of);
988 printAllocInfoSeg(data,func,of);
989 printAllocInfoSeg(xdata,func,of);
990 printAllocInfoSeg(idata,func,of);
991 printAllocInfoSeg(sfr,func,of);
992 printAllocInfoSeg(sfrbit,func,of);