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) {
387 if (port->mem.default_globl_map != xdata) {
388 /* set the output class */
389 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
390 /* generate the symbol */
394 SPEC_SCLS (sym->etype) = S_XDATA;
398 /* if code change to constant */
399 if (SPEC_SCLS (sym->etype) == S_CODE) {
400 SPEC_OCLS (sym->etype) = statsg;
405 if (SPEC_SCLS (sym->etype) == S_XDATA)
407 // should we move this to the initialized data segment?
408 if (port->genXINIT &&
409 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
410 SPEC_OCLS(sym->etype)=xidata;
412 SPEC_OCLS (sym->etype) = xdata;
418 if (SPEC_SCLS (sym->etype) == S_IDATA)
420 SPEC_OCLS (sym->etype) = idata;
426 if (SPEC_SCLS (sym->etype) == S_EEPROM)
428 SPEC_OCLS (sym->etype) = eeprom;
436 /*-----------------------------------------------------------------*/
437 /* allocParms - parameters are always passed on stack */
438 /*-----------------------------------------------------------------*/
440 allocParms (value * val)
445 for (lval = val; lval; lval = lval->next, pNum++)
448 /* check the declaration */
449 checkDecl (lval->sym, 0);
451 /* if this a register parm then allocate
452 it as a local variable by adding it
453 to the first block we see in the body */
454 if (IS_REGPARM (lval->etype))
457 /* mark it as my parameter */
458 lval->sym->ismyparm = 1;
459 lval->sym->localof = currFunc;
462 /* if automatic variables r 2b stacked */
463 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
467 lval->sym->onStack = 1;
469 /* choose which stack 2 use */
470 /* use xternal stack */
471 if (options.useXstack)
473 /* PENDING: stack direction support */
474 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
475 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
476 xstackPtr - getSize (lval->type);
477 xstackPtr -= getSize (lval->type);
480 { /* use internal stack */
481 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
482 if (port->stack.direction > 0)
484 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
485 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
486 getSize (lval->type) -
487 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
488 stackPtr -= getSize (lval->type);
492 /* This looks like the wrong order but it turns out OK... */
493 /* PENDING: isr, bank overhead, ... */
494 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
496 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
497 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
499 stackPtr += getSize (lval->type);
502 allocIntoSeg (lval->sym);
505 { /* allocate them in the automatic space */
506 /* generate a unique name */
507 sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
508 strcpy (lval->name, lval->sym->rname);
510 /* if declared in external storage */
511 if (SPEC_SCLS (lval->etype) == S_XDATA)
512 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
514 /* other wise depending on the memory model
515 note here that we put it into the overlay segment
516 first, we will remove it from the overlay segment
517 after the overlay determination has been done */
518 if (options.model == MODEL_SMALL)
520 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
521 (options.noOverlay ? port->mem.default_local_map
526 SPEC_SCLS (lval->etype) = S_XDATA;
527 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
529 allocIntoSeg (lval->sym);
536 /*-----------------------------------------------------------------*/
537 /* deallocParms - parameters are always passed on stack */
538 /*-----------------------------------------------------------------*/
540 deallocParms (value * val)
544 for (lval = val; lval; lval = lval->next)
547 /* unmark is myparm */
548 lval->sym->ismyparm = 0;
549 /* if on stack then depending on which stack */
551 /* delete it from the symbol table */
552 deleteSym (SymbolTab, lval->sym, lval->sym->name);
554 if (!lval->sym->isref)
556 lval->sym->allocreq = 1;
557 werror (W_NO_REFERENCE, currFunc->name,
558 "function argument", lval->sym->name);
561 /* move the rname if any to the name for both val & sym */
562 /* and leave a copy of it in the symbol table */
563 if (lval->sym->rname[0])
565 char buffer[SDCC_NAME_MAX];
566 strcpy (buffer, lval->sym->rname);
567 lval->sym = copySymbol (lval->sym);
568 strcpy (lval->sym->rname, buffer);
569 strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname));
570 addSym (SymbolTab, lval->sym, lval->sym->name,
571 lval->sym->level, lval->sym->block, 1);
572 lval->sym->_isparm = 1;
573 addSet (&operKeyReset, lval->sym);
581 /*-----------------------------------------------------------------*/
582 /* allocLocal - allocate local variables */
583 /*-----------------------------------------------------------------*/
585 allocLocal (symbol * sym)
588 /* generate an unique name */
589 sprintf (sym->rname, "%s%s_%s_%d_%d",
591 currFunc->name, sym->name, sym->level, sym->block);
594 sym->localof = currFunc;
596 /* if this is a static variable */
597 if (IS_STATIC (sym->etype))
604 /* if volatile then */
605 if (IS_VOLATILE (sym->etype))
608 /* this is automatic */
610 /* if it to be placed on the stack */
611 if (options.stackAuto || reentrant) {
613 if (options.useXstack) {
614 /* PENDING: stack direction for xstack */
615 SPEC_OCLS (sym->etype) = xstack;
616 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
617 xstackPtr += getSize (sym->type);
619 SPEC_OCLS (sym->etype) = istack;
620 if (port->stack.direction > 0) {
621 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
622 stackPtr += getSize (sym->type);
624 stackPtr -= getSize (sym->type);
625 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
632 /* else depending on the storage class specified */
633 if (SPEC_SCLS (sym->etype) == S_XDATA)
635 SPEC_OCLS (sym->etype) = xdata;
640 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
641 SPEC_OCLS (sym->etype) = statsg;
646 if (SPEC_SCLS (sym->etype) == S_IDATA)
648 SPEC_OCLS (sym->etype) = idata;
654 /* if this is a function then assign code space */
655 if (IS_FUNC (sym->type))
657 SPEC_OCLS (sym->etype) = code;
661 /* if this is a SFR or SBIT */
662 if (SPEC_SCLS (sym->etype) == S_SFR ||
663 SPEC_SCLS (sym->etype) == S_SBIT)
666 /* if both absolute address & initial */
667 /* value specified then error */
668 if (IS_ABSOLUTE (sym->etype) && sym->ival)
670 werror (E_SFR_INIT, sym->name);
674 SPEC_OCLS (sym->etype) =
675 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
681 /* if this is a bit variable and no storage class */
682 if (SPEC_NOUN (sym->etype) == V_BIT
683 && (SPEC_SCLS (sym->etype) == S_BIT))
685 SPEC_OCLS (sym->etype) = bit;
690 if (SPEC_SCLS (sym->etype) == S_DATA)
692 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
697 if (SPEC_SCLS (sym->etype) == S_EEPROM)
699 SPEC_OCLS (sym->etype) = eeprom;
704 /* again note that we have put it into the overlay segment
705 will remove and put into the 'data' segment if required after
706 overlay analysis has been done */
707 if (options.model == MODEL_SMALL) {
708 SPEC_OCLS (sym->etype) =
709 (options.noOverlay ? port->mem.default_local_map
712 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
717 /*-----------------------------------------------------------------*/
718 /* deallocLocal - deallocates the local variables */
719 /*-----------------------------------------------------------------*/
721 deallocLocal (symbol * csym)
725 for (sym = csym; sym; sym = sym->next)
730 /* if it is on the stack */
733 if (options.useXstack)
734 xstackPtr -= getSize (sym->type);
736 stackPtr -= getSize (sym->type);
738 /* if not used give a warning */
739 if (!sym->isref && !IS_STATIC (sym->etype))
740 werror (W_NO_REFERENCE, currFunc->name,
741 "local variable", sym->name);
742 /* now delete it from the symbol table */
743 deleteSym (SymbolTab, sym, sym->name);
747 /*-----------------------------------------------------------------*/
748 /* overlay2data - moves declarations from the overlay seg to data */
749 /*-----------------------------------------------------------------*/
755 for (sym = setFirstItem (overlay->syms); sym;
756 sym = setNextItem (overlay->syms))
759 SPEC_OCLS (sym->etype) = data;
763 setToNull ((void **) &overlay->syms);
767 /*-----------------------------------------------------------------*/
768 /* overlay2Set - will add all symbols from the overlay segment to */
769 /* the set of sets containing the overlable symbols */
770 /*-----------------------------------------------------------------*/
777 for (sym = setFirstItem (overlay->syms); sym;
778 sym = setNextItem (overlay->syms))
784 setToNull ((void **) &overlay->syms);
785 addSet (&ovrSetSets, oset);
789 /*-----------------------------------------------------------------*/
790 /* allocVariables - creates decl & assign storage class for a v */
791 /*-----------------------------------------------------------------*/
793 allocVariables (symbol * symChain)
800 /* go thru the symbol chain */
801 for (sym = symChain; sym; sym = sym->next)
804 /* if this is a typedef then add it */
805 /* to the typedef table */
806 if (IS_TYPEDEF (sym->etype))
808 /* check if the typedef already exists */
809 csym = findSym (TypedefTab, NULL, sym->name);
810 if (csym && csym->level == sym->level)
811 werror (E_DUPLICATE_TYPEDEF, sym->name);
813 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
814 continue; /* go to the next one */
816 /* make sure it already exist */
817 csym = findSymWithLevel (SymbolTab, sym);
818 if (!csym || (csym && csym->level != sym->level))
821 /* check the declaration */
824 /* if this is a function or a pointer to function */
825 /* then args processing */
826 if (funcInChain (csym->type))
828 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
829 processFuncArgs (csym);
831 /* if register bank specified then update maxRegBank */
832 if (maxRegBank < FUNC_REGBANK (csym->type))
833 maxRegBank = FUNC_REGBANK (csym->type);
836 /* if this is a extern variable then change the */
837 /* level to zero temporarily */
838 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
840 saveLevel = csym->level;
844 /* if this is a literal then it is an enumerated */
845 /* type so need not allocate it space for it */
846 if (IS_LITERAL (sym->etype))
849 /* generate the actual declaration */
854 stack += getSize (csym->type);
859 /* restore the level */
860 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
861 csym->level = saveLevel;
867 /*-----------------------------------------------------------------*/
868 /* redoStackOffsets :- will reassign the values for stack offsets */
869 /*-----------------------------------------------------------------*/
871 redoStackOffsets (void)
877 /* after register allocation is complete we know
878 which variables will need to be assigned space
879 on the stack. We will eliminate those variables
880 which do not have the allocReq flag thus reducing
882 for (sym = setFirstItem (istack->syms); sym;
883 sym = setNextItem (istack->syms))
886 int size = getSize (sym->type);
887 /* nothing to do with parameters so continue */
888 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
891 if (IS_AGGREGATE (sym->type))
893 if (port->stack.direction > 0)
895 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
901 SPEC_STAK (sym->etype) = sym->stack = sPtr;
906 /* if allocation not required then subtract
907 size from overall stack size & continue */
910 currFunc->stack -= size;
911 SPEC_STAK (currFunc->etype) -= size;
915 if (port->stack.direction > 0)
917 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
923 SPEC_STAK (sym->etype) = sym->stack = sPtr;
927 /* do the same for the external stack */
929 for (sym = setFirstItem (xstack->syms); sym;
930 sym = setNextItem (xstack->syms))
933 int size = getSize (sym->type);
934 /* nothing to do with parameters so continue */
935 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
938 if (IS_AGGREGATE (sym->type))
940 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
945 /* if allocation not required then subtract
946 size from overall stack size & continue */
949 currFunc->xstack -= size;
950 SPEC_STAK (currFunc->etype) -= size;
954 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
958 /* if the debug option is set then output the
959 symbols to the map file */
962 for (sym = setFirstItem (istack->syms); sym;
963 sym = setNextItem (istack->syms))
964 cdbSymbol (sym, cdbFile, FALSE, FALSE);
966 for (sym = setFirstItem (xstack->syms); sym;
967 sym = setNextItem (xstack->syms))
968 cdbSymbol (sym, cdbFile, FALSE, FALSE);
972 /*-----------------------------------------------------------------*/
973 /* printAllocInfoSeg- print the allocation for a given section */
974 /*-----------------------------------------------------------------*/
976 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
985 for (sym = setFirstItem (map->syms); sym;
986 sym = setNextItem (map->syms))
991 if (sym->localof != func)
993 fprintf (of, ";%-25s Allocated to ", sym->name);
995 /* if assigned to registers */
996 if (!sym->allocreq && sym->reqv)
999 sym = OP_SYMBOL (sym->reqv);
1000 fprintf (of, "registers ");
1001 for (i = 0; i < 4 && sym->regs[i]; i++)
1002 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1010 fprintf (of, "stack - offset %d\n", sym->stack);
1014 /* otherwise give rname */
1015 fprintf (of, "in memory with name '%s'\n", sym->rname);
1019 /*-----------------------------------------------------------------*/
1020 /* canOverlayLocals - returns true if the local variables can overlayed */
1021 /*-----------------------------------------------------------------*/
1023 canOverlayLocals (eBBlock ** ebbs, int count)
1026 /* if staticAuto is in effect or the current function
1027 being compiled is reentrant or the overlay segment
1028 is empty or no overlay option is in effect then */
1029 if (options.noOverlay ||
1030 options.stackAuto ||
1032 (IFFUNC_ISREENT (currFunc->type) ||
1033 FUNC_ISISR (currFunc->type))) ||
1034 elementsInSet (overlay->syms) == 0)
1038 /* if this is a forces overlay */
1039 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1041 /* otherwise do thru the blocks and see if there
1042 any function calls if found then return false */
1043 for (i = 0; i < count; i++)
1047 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1049 if (ic->op == CALL) {
1050 sym_link *ftype = operandType(IC_LEFT(ic));
1051 /* builtins only can use overlays */
1052 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1053 } else if (ic->op == PCALL) return FALSE;
1057 /* no function calls found return TRUE */
1061 /*-----------------------------------------------------------------*/
1062 /* doOverlays - move the overlay segment to appropriate location */
1063 /*-----------------------------------------------------------------*/
1065 doOverlays (eBBlock ** ebbs, int count)
1067 /* check if the parameters and local variables
1068 of this function can be put in the overlay segment
1069 This check is essentially to see if the function
1070 calls any other functions if yes then we cannot
1072 if (canOverlayLocals (ebbs, count))
1073 /* if we can then put the parameters &
1074 local variables in the overlay set */
1077 /* otherwise put them into data where
1082 /*-----------------------------------------------------------------*/
1083 /* printAllocInfo - prints allocation information for a function */
1084 /*-----------------------------------------------------------------*/
1086 printAllocInfo (symbol * func, FILE * of)
1091 /* must be called after register allocation is complete */
1092 fprintf (of, ";------------------------------------------------------------\n");
1093 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1094 fprintf (of, ";------------------------------------------------------------\n");
1096 printAllocInfoSeg (xstack, func, of);
1097 printAllocInfoSeg (istack, func, of);
1098 printAllocInfoSeg (code, func, of);
1099 printAllocInfoSeg (data, func, of);
1100 printAllocInfoSeg (xdata, func, of);
1101 printAllocInfoSeg (idata, func, of);
1102 printAllocInfoSeg (sfr, func, of);
1103 printAllocInfoSeg (sfrbit, func, of);