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 *xidata = NULL; /* the initialized xdata */
14 memmap *xinit = NULL; /* the initializers for xidata */
15 memmap *idata = NULL; /* internal data upto 256 */
16 memmap *bit = NULL; /* bit addressable space */
17 memmap *statsg = NULL; /* the constant data segment */
18 memmap *sfr = NULL; /* register space */
19 memmap *reg = NULL; /* register space */
20 memmap *sfrbit = NULL; /* sfr bit space */
21 memmap *generic = NULL; /* is a generic pointer */
22 memmap *overlay = NULL; /* overlay segment */
23 memmap *eeprom = NULL; /* eeprom location */
24 memmap *home = NULL; /* Unswitchable code bank */
26 /* this is a set of sets each set containing
27 symbols in a single overlay */
28 set *ovrSetSets = NULL;
31 int fatalError = 0; /* fatal error flag */
33 /*-----------------------------------------------------------------*/
34 /* allocMap - allocates a memory map */
35 /*-----------------------------------------------------------------*/
37 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 = Safe_alloc (sizeof (memmap))))
53 werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
57 memset (map, ZERO, sizeof (memmap));
63 map->codesp = codemap;
67 map->ptrType = ptrType;
68 if (!(map->oFile = tempfile ()))
70 werror (E_TMPFILE_FAILED);
73 addSetHead (&tmpfileSet, map->oFile);
78 /*-----------------------------------------------------------------*/
79 /* initMem - allocates and initializes all the segments */
80 /*-----------------------------------------------------------------*/
84 /* allocate all the segments */
85 /* xternal stack segment ;
93 POINTER-TYPE - FPOINTER
95 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
97 /* internal stack segment ;
105 POINTER-TYPE - POINTER
107 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER);
117 POINTER-TYPE - CPOINTER
119 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
129 POINTER-TYPE - CPOINTER
131 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
133 /* Static segment (code for variables );
141 POINTER-TYPE - CPOINTER
143 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
145 /* Data segment - internal storage segment ;
153 POINTER-TYPE - POINTER
155 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
157 /* overlay segment - same as internal storage segment ;
165 POINTER-TYPE - POINTER
167 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
169 /* Xternal Data segment -
177 POINTER-TYPE - FPOINTER
179 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
180 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
181 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
183 /* Inderectly addressed internal data segment
191 POINTER-TYPE - IPOINTER
193 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER);
195 /* Static segment (code for variables );
203 POINTER-TYPE - _NONE_
205 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
207 /* Special function register space :-
215 POINTER-TYPE - _NONE_
217 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
227 POINTER-TYPE - _NONE_
229 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
239 POINTER-TYPE - _NONE_
241 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
251 POINTER-TYPE - EEPPOINTER
253 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
255 /* the unknown map */
256 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
260 /*-----------------------------------------------------------------*/
261 /* allocIntoSeg - puts a symbol into a memory segment */
262 /*-----------------------------------------------------------------*/
264 allocIntoSeg (symbol * sym)
266 memmap *segment = SPEC_OCLS (sym->etype);
267 addSet (&segment->syms, sym);
270 /*-----------------------------------------------------------------*/
271 /* deleteFromSeg - deletes a symbol from segment used when a var */
272 /* firest declared as "extern" then no extern */
273 /*-----------------------------------------------------------------*/
274 void deleteFromSeg(symbol *sym)
276 if (SPEC_OCLS(sym->etype)) {
277 memmap *segment = SPEC_OCLS (sym->etype);
278 deleteSetItem(&segment->syms,sym);
283 /*-----------------------------------------------------------------*/
284 /* allocGlobal - assigns the output segment to a global var */
285 /*-----------------------------------------------------------------*/
287 allocGlobal (symbol * sym)
290 /* symbol name is internal name */
291 if (!sym->level) /* local statics can come here */
292 sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name);
294 /* add it to the operandKey reset */
295 addSet (&operKeyReset, sym);
297 /* if this is a literal e.g. enumerated type */
298 /* put it in the data segment & do nothing */
299 if (IS_LITERAL (sym->etype))
301 SPEC_OCLS (sym->etype) = data;
305 /* if this is a function then assign code space */
306 if (IS_FUNC (sym->type))
308 SPEC_OCLS (sym->etype) = code;
309 /* if this is an interrupt service routine
310 then put it in the interrupt service array */
311 if (FUNC_ISISR (sym->type))
314 if (interrupts[FUNC_INTNO (sym->type)])
315 werror (E_INT_DEFINED,
316 FUNC_INTNO (sym->type),
317 interrupts[FUNC_INTNO (sym->type)]->name);
319 interrupts[FUNC_INTNO (sym->type)] = sym;
321 /* automagically extend the maximum interrupts */
322 if (FUNC_INTNO (sym->type) >= maxInterrupts)
323 maxInterrupts = FUNC_INTNO (sym->type) + 1;
325 /* if it is not compiler defined */
332 /* if this is a SFR or SBIT */
333 if (SPEC_SCLS (sym->etype) == S_SFR ||
334 SPEC_SCLS (sym->etype) == S_SBIT)
337 /* if both absolute address & initial */
338 /* value specified then error */
339 if (IS_ABSOLUTE (sym->etype) && sym->ival)
341 werror (E_SFR_INIT, sym->name);
345 SPEC_OCLS (sym->etype) =
346 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
352 /* if this is a bit variable and no storage class */
353 if (SPEC_NOUN (sym->etype) == V_BIT
354 && SPEC_SCLS (sym->etype) == S_BIT)
356 SPEC_OCLS (sym->etype) = bit;
361 /* if bit storage class */
362 if (SPEC_SCLS (sym->etype) == S_SBIT)
364 SPEC_OCLS (sym->etype) = bit;
369 /* register storage class ignored changed to FIXED */
370 if (SPEC_SCLS (sym->etype) == S_REGISTER)
371 SPEC_SCLS (sym->etype) = S_FIXED;
373 /* if data specified then */
374 if (SPEC_SCLS (sym->etype) == S_DATA)
376 /* set the output class */
377 SPEC_OCLS (sym->etype) = data;
378 /* generate the symbol */
383 /* if it is fixed, then allocate depending on the */
384 /* current memory model,same for automatics */
385 if (SPEC_SCLS (sym->etype) == S_FIXED ||
386 SPEC_SCLS (sym->etype) == S_AUTO)
388 /* set the output class */
389 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
390 /* generate the symbol */
395 /* if code change to constant */
396 if (SPEC_SCLS (sym->etype) == S_CODE) {
397 SPEC_OCLS (sym->etype) = statsg;
402 if (SPEC_SCLS (sym->etype) == S_XDATA)
404 SPEC_OCLS (sym->etype) = xdata;
405 // should we move this to the initialized data segment?
406 if (port->genXINIT &&
407 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
408 SPEC_OCLS(sym->etype)=xidata;
409 addSet(&xidata->syms, sym);
415 if (SPEC_SCLS (sym->etype) == S_IDATA)
417 SPEC_OCLS (sym->etype) = idata;
423 if (SPEC_SCLS (sym->etype) == S_EEPROM)
425 SPEC_OCLS (sym->etype) = eeprom;
433 /*-----------------------------------------------------------------*/
434 /* allocParms - parameters are always passed on stack */
435 /*-----------------------------------------------------------------*/
437 allocParms (value * val)
442 for (lval = val; lval; lval = lval->next, pNum++)
445 /* check the declaration */
446 checkDecl (lval->sym, 0);
448 /* if this a register parm then allocate
449 it as a local variable by adding it
450 to the first block we see in the body */
451 if (IS_REGPARM (lval->etype))
454 /* mark it as my parameter */
455 lval->sym->ismyparm = 1;
456 lval->sym->localof = currFunc;
459 /* if automatic variables r 2b stacked */
460 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
464 lval->sym->onStack = 1;
466 /* choose which stack 2 use */
467 /* use xternal stack */
468 if (options.useXstack)
470 /* PENDING: stack direction support */
471 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
472 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
473 xstackPtr - getSize (lval->type);
474 xstackPtr -= getSize (lval->type);
477 { /* use internal stack */
478 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
479 if (port->stack.direction > 0)
481 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
482 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
483 getSize (lval->type) -
484 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
485 stackPtr -= getSize (lval->type);
489 /* This looks like the wrong order but it turns out OK... */
490 /* PENDING: isr, bank overhead, ... */
491 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
493 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
494 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
496 stackPtr += getSize (lval->type);
499 allocIntoSeg (lval->sym);
502 { /* allocate them in the automatic space */
503 /* generate a unique name */
504 sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
505 strcpy (lval->name, lval->sym->rname);
507 /* if declared in external storage */
508 if (SPEC_SCLS (lval->etype) == S_XDATA)
509 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
511 /* other wise depending on the memory model
512 note here that we put it into the overlay segment
513 first, we will remove it from the overlay segment
514 after the overlay determination has been done */
515 if (options.model == MODEL_SMALL)
517 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
518 (options.noOverlay ? port->mem.default_local_map
523 SPEC_SCLS (lval->etype) = S_XDATA;
524 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
526 allocIntoSeg (lval->sym);
533 /*-----------------------------------------------------------------*/
534 /* deallocParms - parameters are always passed on stack */
535 /*-----------------------------------------------------------------*/
537 deallocParms (value * val)
541 for (lval = val; lval; lval = lval->next)
544 /* unmark is myparm */
545 lval->sym->ismyparm = 0;
546 /* if on stack then depending on which stack */
548 /* delete it from the symbol table */
549 deleteSym (SymbolTab, lval->sym, lval->sym->name);
551 if (!lval->sym->isref)
553 lval->sym->allocreq = 1;
554 werror (W_NO_REFERENCE, currFunc->name,
555 "function argument", lval->sym->name);
558 /* move the rname if any to the name for both val & sym */
559 /* and leave a copy of it in the symbol table */
560 if (lval->sym->rname[0])
562 char buffer[SDCC_NAME_MAX];
563 strcpy (buffer, lval->sym->rname);
564 lval->sym = copySymbol (lval->sym);
565 strcpy (lval->sym->rname, buffer);
566 strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
567 addSym (SymbolTab, lval->sym, lval->sym->name,
568 lval->sym->level, lval->sym->block, 1);
569 lval->sym->_isparm = 1;
570 addSet (&operKeyReset, lval->sym);
578 /*-----------------------------------------------------------------*/
579 /* allocLocal - allocate local variables */
580 /*-----------------------------------------------------------------*/
582 allocLocal (symbol * sym)
585 /* generate an unique name */
586 sprintf (sym->rname, "%s%s_%s_%d_%d",
588 currFunc->name, sym->name, sym->level, sym->block);
591 sym->localof = currFunc;
593 /* if this is a static variable */
594 if (IS_STATIC (sym->etype))
601 /* if volatile then */
602 if (IS_VOLATILE (sym->etype))
605 /* this is automatic */
607 /* if it to be placed on the stack */
608 if (options.stackAuto || reentrant) {
610 if (options.useXstack) {
611 /* PENDING: stack direction for xstack */
612 SPEC_OCLS (sym->etype) = xstack;
613 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
614 xstackPtr += getSize (sym->type);
616 SPEC_OCLS (sym->etype) = istack;
617 if (port->stack.direction > 0) {
618 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
619 stackPtr += getSize (sym->type);
621 stackPtr -= getSize (sym->type);
622 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
629 /* else depending on the storage class specified */
630 if (SPEC_SCLS (sym->etype) == S_XDATA)
632 SPEC_OCLS (sym->etype) = xdata;
637 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
638 SPEC_OCLS (sym->etype) = statsg;
643 if (SPEC_SCLS (sym->etype) == S_IDATA)
645 SPEC_OCLS (sym->etype) = idata;
651 /* if this is a function then assign code space */
652 if (IS_FUNC (sym->type))
654 SPEC_OCLS (sym->etype) = code;
658 /* if this is a SFR or SBIT */
659 if (SPEC_SCLS (sym->etype) == S_SFR ||
660 SPEC_SCLS (sym->etype) == S_SBIT)
663 /* if both absolute address & initial */
664 /* value specified then error */
665 if (IS_ABSOLUTE (sym->etype) && sym->ival)
667 werror (E_SFR_INIT, sym->name);
671 SPEC_OCLS (sym->etype) =
672 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
678 /* if this is a bit variable and no storage class */
679 if (SPEC_NOUN (sym->etype) == V_BIT
680 && (SPEC_SCLS (sym->etype) == S_BIT))
682 SPEC_OCLS (sym->etype) = bit;
687 if (SPEC_SCLS (sym->etype) == S_DATA)
689 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
694 if (SPEC_SCLS (sym->etype) == S_EEPROM)
696 SPEC_OCLS (sym->etype) = eeprom;
701 /* again note that we have put it into the overlay segment
702 will remove and put into the 'data' segment if required after
703 overlay analysis has been done */
704 if (options.model == MODEL_SMALL) {
705 SPEC_OCLS (sym->etype) =
706 (options.noOverlay ? port->mem.default_local_map
709 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
714 /*-----------------------------------------------------------------*/
715 /* deallocLocal - deallocates the local variables */
716 /*-----------------------------------------------------------------*/
718 deallocLocal (symbol * csym)
722 for (sym = csym; sym; sym = sym->next)
727 /* if it is on the stack */
730 if (options.useXstack)
731 xstackPtr -= getSize (sym->type);
733 stackPtr -= getSize (sym->type);
735 /* if not used give a warning */
736 if (!sym->isref && !IS_STATIC (sym->etype))
737 werror (W_NO_REFERENCE, currFunc->name,
738 "local variable", sym->name);
739 /* now delete it from the symbol table */
740 deleteSym (SymbolTab, sym, sym->name);
744 /*-----------------------------------------------------------------*/
745 /* overlay2data - moves declarations from the overlay seg to data */
746 /*-----------------------------------------------------------------*/
752 for (sym = setFirstItem (overlay->syms); sym;
753 sym = setNextItem (overlay->syms))
756 SPEC_OCLS (sym->etype) = data;
760 setToNull ((void **) &overlay->syms);
764 /*-----------------------------------------------------------------*/
765 /* overlay2Set - will add all symbols from the overlay segment to */
766 /* the set of sets containing the overlable symbols */
767 /*-----------------------------------------------------------------*/
774 for (sym = setFirstItem (overlay->syms); sym;
775 sym = setNextItem (overlay->syms))
781 setToNull ((void **) &overlay->syms);
782 addSet (&ovrSetSets, oset);
786 /*-----------------------------------------------------------------*/
787 /* allocVariables - creates decl & assign storage class for a v */
788 /*-----------------------------------------------------------------*/
790 allocVariables (symbol * symChain)
797 /* go thru the symbol chain */
798 for (sym = symChain; sym; sym = sym->next)
801 /* if this is a typedef then add it */
802 /* to the typedef table */
803 if (IS_TYPEDEF (sym->etype))
805 /* check if the typedef already exists */
806 csym = findSym (TypedefTab, NULL, sym->name);
807 if (csym && csym->level == sym->level)
808 werror (E_DUPLICATE_TYPEDEF, sym->name);
810 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
811 continue; /* go to the next one */
813 /* make sure it already exist */
814 csym = findSymWithLevel (SymbolTab, sym);
815 if (!csym || (csym && csym->level != sym->level))
818 /* check the declaration */
821 /* if this is a function or a pointer to function */
822 /* then args processing */
823 if (funcInChain (csym->type))
825 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
826 processFuncArgs (csym);
828 /* if register bank specified then update maxRegBank */
829 if (maxRegBank < FUNC_REGBANK (csym->type))
830 maxRegBank = FUNC_REGBANK (csym->type);
833 /* if this is a extern variable then change the */
834 /* level to zero temporarily */
835 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
837 saveLevel = csym->level;
841 /* if this is a literal then it is an enumerated */
842 /* type so need not allocate it space for it */
843 if (IS_LITERAL (sym->etype))
846 /* generate the actual declaration */
851 stack += getSize (csym->type);
856 /* restore the level */
857 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
858 csym->level = saveLevel;
864 /*-----------------------------------------------------------------*/
865 /* redoStackOffsets :- will reassign the values for stack offsets */
866 /*-----------------------------------------------------------------*/
868 redoStackOffsets (void)
874 /* after register allocation is complete we know
875 which variables will need to be assigned space
876 on the stack. We will eliminate those variables
877 which do not have the allocReq flag thus reducing
879 for (sym = setFirstItem (istack->syms); sym;
880 sym = setNextItem (istack->syms))
883 int size = getSize (sym->type);
884 /* nothing to do with parameters so continue */
885 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
888 if (IS_AGGREGATE (sym->type))
890 if (port->stack.direction > 0)
892 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
898 SPEC_STAK (sym->etype) = sym->stack = sPtr;
903 /* if allocation not required then subtract
904 size from overall stack size & continue */
907 currFunc->stack -= size;
908 SPEC_STAK (currFunc->etype) -= size;
912 if (port->stack.direction > 0)
914 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
920 SPEC_STAK (sym->etype) = sym->stack = sPtr;
924 /* do the same for the external stack */
926 for (sym = setFirstItem (xstack->syms); sym;
927 sym = setNextItem (xstack->syms))
930 int size = getSize (sym->type);
931 /* nothing to do with parameters so continue */
932 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
935 if (IS_AGGREGATE (sym->type))
937 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
942 /* if allocation not required then subtract
943 size from overall stack size & continue */
946 currFunc->xstack -= size;
947 SPEC_STAK (currFunc->etype) -= size;
951 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
955 /* if the debug option is set then output the
956 symbols to the map file */
959 for (sym = setFirstItem (istack->syms); sym;
960 sym = setNextItem (istack->syms))
961 cdbSymbol (sym, cdbFile, FALSE, FALSE);
963 for (sym = setFirstItem (xstack->syms); sym;
964 sym = setNextItem (xstack->syms))
965 cdbSymbol (sym, cdbFile, FALSE, FALSE);
969 /*-----------------------------------------------------------------*/
970 /* printAllocInfoSeg- print the allocation for a given section */
971 /*-----------------------------------------------------------------*/
973 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
982 for (sym = setFirstItem (map->syms); sym;
983 sym = setNextItem (map->syms))
988 if (sym->localof != func)
990 fprintf (of, ";%-25s Allocated to ", sym->name);
992 /* if assigned to registers */
993 if (!sym->allocreq && sym->reqv)
996 sym = OP_SYMBOL (sym->reqv);
997 fprintf (of, "registers ");
998 for (i = 0; i < 4 && sym->regs[i]; i++)
999 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1007 fprintf (of, "stack - offset %d\n", sym->stack);
1011 /* otherwise give rname */
1012 fprintf (of, "in memory with name '%s'\n", sym->rname);
1016 /*-----------------------------------------------------------------*/
1017 /* canOverlayLocals - returns true if the local variables can overlayed */
1018 /*-----------------------------------------------------------------*/
1020 canOverlayLocals (eBBlock ** ebbs, int count)
1023 /* if staticAuto is in effect or the current function
1024 being compiled is reentrant or the overlay segment
1025 is empty or no overlay option is in effect then */
1026 if (options.noOverlay ||
1027 options.stackAuto ||
1029 (IFFUNC_ISREENT (currFunc->type) ||
1030 FUNC_ISISR (currFunc->type))) ||
1031 elementsInSet (overlay->syms) == 0)
1035 /* if this is a forces overlay */
1036 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1038 /* otherwise do thru the blocks and see if there
1039 any function calls if found then return false */
1040 for (i = 0; i < count; i++)
1044 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1046 if (ic->op == CALL) {
1047 sym_link *ftype = operandType(IC_LEFT(ic));
1048 /* builtins only can use overlays */
1049 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1050 } else if (ic->op == PCALL) return FALSE;
1054 /* no function calls found return TRUE */
1058 /*-----------------------------------------------------------------*/
1059 /* doOverlays - move the overlay segment to appropriate location */
1060 /*-----------------------------------------------------------------*/
1062 doOverlays (eBBlock ** ebbs, int count)
1064 /* check if the parameters and local variables
1065 of this function can be put in the overlay segment
1066 This check is essentially to see if the function
1067 calls any other functions if yes then we cannot
1069 if (canOverlayLocals (ebbs, count))
1070 /* if we can then put the parameters &
1071 local variables in the overlay set */
1074 /* otherwise put them into data where
1079 /*-----------------------------------------------------------------*/
1080 /* printAllocInfo - prints allocation information for a function */
1081 /*-----------------------------------------------------------------*/
1083 printAllocInfo (symbol * func, FILE * of)
1088 /* must be called after register allocation is complete */
1089 fprintf (of, ";------------------------------------------------------------\n");
1090 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1091 fprintf (of, ";------------------------------------------------------------\n");
1093 printAllocInfoSeg (xstack, func, of);
1094 printAllocInfoSeg (istack, func, of);
1095 printAllocInfoSeg (code, func, of);
1096 printAllocInfoSeg (data, func, of);
1097 printAllocInfoSeg (xdata, func, of);
1098 printAllocInfoSeg (idata, func, of);
1099 printAllocInfoSeg (sfr, func, of);
1100 printAllocInfoSeg (sfrbit, func, of);