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
108 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc,
109 ISTACK_NAME, 'B', POINTER);
122 POINTER-TYPE - CPOINTER
124 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
134 POINTER-TYPE - CPOINTER
136 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
138 /* Static segment (code for variables );
146 POINTER-TYPE - CPOINTER
148 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
150 /* Data segment - internal storage segment ;
158 POINTER-TYPE - POINTER
160 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
162 /* overlay segment - same as internal storage segment ;
170 POINTER-TYPE - POINTER
173 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
178 /* Xternal Data segment -
186 POINTER-TYPE - FPOINTER
188 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
189 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
190 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
192 /* Inderectly addressed internal data segment
200 POINTER-TYPE - IPOINTER
203 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,
204 IDATA_NAME, 'G', IPOINTER);
209 /* Static segment (code for variables );
217 POINTER-TYPE - _NONE_
219 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
221 /* Special function register space :-
229 POINTER-TYPE - _NONE_
231 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
241 POINTER-TYPE - _NONE_
243 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
253 POINTER-TYPE - _NONE_
255 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
265 POINTER-TYPE - EEPPOINTER
267 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
269 /* the unknown map */
270 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
274 /*-----------------------------------------------------------------*/
275 /* allocIntoSeg - puts a symbol into a memory segment */
276 /*-----------------------------------------------------------------*/
278 allocIntoSeg (symbol * sym)
280 memmap *segment = SPEC_OCLS (sym->etype);
281 addSet (&segment->syms, sym);
284 /*-----------------------------------------------------------------*/
285 /* deleteFromSeg - deletes a symbol from segment used when a var */
286 /* firest declared as "extern" then no extern */
287 /*-----------------------------------------------------------------*/
288 void deleteFromSeg(symbol *sym)
290 if (SPEC_OCLS(sym->etype)) {
291 memmap *segment = SPEC_OCLS (sym->etype);
292 deleteSetItem(&segment->syms,sym);
297 /*-----------------------------------------------------------------*/
298 /* allocGlobal - assigns the output segment to a global var */
299 /*-----------------------------------------------------------------*/
301 allocGlobal (symbol * sym)
304 /* symbol name is internal name */
305 if (!sym->level) /* local statics can come here */
306 SNPRINTF (sym->rname, sizeof(sym->rname),
307 "%s%s", port->fun_prefix, sym->name);
309 /* add it to the operandKey reset */
310 addSet (&operKeyReset, sym);
312 /* if this is a literal e.g. enumerated type */
313 /* put it in the data segment & do nothing */
314 if (IS_LITERAL (sym->etype))
316 SPEC_OCLS (sym->etype) = data;
320 /* if this is a function then assign code space */
321 if (IS_FUNC (sym->type))
323 SPEC_OCLS (sym->etype) = code;
324 /* if this is an interrupt service routine
325 then put it in the interrupt service array */
326 if (FUNC_ISISR (sym->type) && !options.noiv)
329 if (interrupts[FUNC_INTNO (sym->type)])
330 werror (E_INT_DEFINED,
331 FUNC_INTNO (sym->type),
332 interrupts[FUNC_INTNO (sym->type)]->name);
334 interrupts[FUNC_INTNO (sym->type)] = sym;
336 /* automagically extend the maximum interrupts */
337 if (FUNC_INTNO (sym->type) >= maxInterrupts)
338 maxInterrupts = FUNC_INTNO (sym->type) + 1;
340 /* if it is not compiler defined */
347 /* if this is a SFR or SBIT */
348 if (SPEC_SCLS (sym->etype) == S_SFR ||
349 SPEC_SCLS (sym->etype) == S_SBIT)
352 /* if both absolute address & initial */
353 /* value specified then error */
354 if (IS_ABSOLUTE (sym->etype) && sym->ival)
356 werror (E_SFR_INIT, sym->name);
360 SPEC_OCLS (sym->etype) =
361 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
367 /* if this is a bit variable and no storage class */
368 if (SPEC_NOUN (sym->etype) == V_BIT
369 && SPEC_SCLS (sym->etype) == S_BIT)
371 SPEC_OCLS (sym->etype) = bit;
376 /* if bit storage class */
377 if (SPEC_SCLS (sym->etype) == S_SBIT)
379 SPEC_OCLS (sym->etype) = bit;
384 /* register storage class ignored changed to FIXED */
385 if (SPEC_SCLS (sym->etype) == S_REGISTER)
386 SPEC_SCLS (sym->etype) = S_FIXED;
388 /* if data specified then */
389 if (SPEC_SCLS (sym->etype) == S_DATA)
391 /* set the output class */
392 SPEC_OCLS (sym->etype) = data;
393 /* generate the symbol */
398 /* if it is fixed, then allocate depending on the */
399 /* current memory model, same for automatics */
400 if (SPEC_SCLS (sym->etype) == S_FIXED ||
401 SPEC_SCLS (sym->etype) == S_AUTO) {
402 if (port->mem.default_globl_map != xdata) {
403 /* set the output class */
404 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
405 /* generate the symbol */
409 SPEC_SCLS (sym->etype) = S_XDATA;
413 /* if code change to constant */
414 if (SPEC_SCLS (sym->etype) == S_CODE) {
415 SPEC_OCLS (sym->etype) = statsg;
420 if (SPEC_SCLS (sym->etype) == S_XDATA)
422 // should we move this to the initialized data segment?
423 if (port->genXINIT &&
424 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
425 SPEC_OCLS(sym->etype)=xidata;
427 SPEC_OCLS (sym->etype) = xdata;
433 if (SPEC_SCLS (sym->etype) == S_IDATA)
435 SPEC_OCLS (sym->etype) = idata;
441 if (SPEC_SCLS (sym->etype) == S_EEPROM)
443 SPEC_OCLS (sym->etype) = eeprom;
451 /*-----------------------------------------------------------------*/
452 /* allocParms - parameters are always passed on stack */
453 /*-----------------------------------------------------------------*/
455 allocParms (value * val)
460 for (lval = val; lval; lval = lval->next, pNum++)
463 /* check the declaration */
464 checkDecl (lval->sym, 0);
466 /* if this a register parm then allocate
467 it as a local variable by adding it
468 to the first block we see in the body */
469 if (IS_REGPARM (lval->etype))
472 /* mark it as my parameter */
473 lval->sym->ismyparm = 1;
474 lval->sym->localof = currFunc;
477 /* if automatic variables r 2b stacked */
478 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
482 lval->sym->onStack = 1;
484 /* choose which stack 2 use */
485 /* use xternal stack */
486 if (options.useXstack)
488 /* PENDING: stack direction support */
489 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
490 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
491 xstackPtr - getSize (lval->type);
492 xstackPtr -= getSize (lval->type);
495 { /* use internal stack */
496 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
497 if (port->stack.direction > 0)
499 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
500 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
501 getSize (lval->type) -
502 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
503 stackPtr -= getSize (lval->type);
507 /* This looks like the wrong order but it turns out OK... */
508 /* PENDING: isr, bank overhead, ... */
509 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
511 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
512 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
514 stackPtr += getSize (lval->type);
517 allocIntoSeg (lval->sym);
520 { /* allocate them in the automatic space */
521 /* generate a unique name */
522 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
523 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
524 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
526 /* if declared in external storage */
527 if (SPEC_SCLS (lval->etype) == S_XDATA)
528 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
530 /* other wise depending on the memory model
531 note here that we put it into the overlay segment
532 first, we will remove it from the overlay segment
533 after the overlay determination has been done */
534 if (options.model == MODEL_SMALL)
536 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
537 (options.noOverlay ? port->mem.default_local_map
542 SPEC_SCLS (lval->etype) = S_XDATA;
543 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
545 allocIntoSeg (lval->sym);
552 /*-----------------------------------------------------------------*/
553 /* deallocParms - parameters are always passed on stack */
554 /*-----------------------------------------------------------------*/
556 deallocParms (value * val)
560 for (lval = val; lval; lval = lval->next)
563 /* unmark is myparm */
564 lval->sym->ismyparm = 0;
566 /* delete it from the symbol table */
567 deleteSym (SymbolTab, lval->sym, lval->sym->name);
569 if (!lval->sym->isref)
571 lval->sym->allocreq = 0;
572 werror (W_NO_REFERENCE, currFunc->name,
573 "function argument", lval->sym->name);
576 /* move the rname if any to the name for both val & sym */
577 /* and leave a copy of it in the symbol table */
578 if (lval->sym->rname[0])
580 char buffer[SDCC_NAME_MAX];
581 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
582 lval->sym = copySymbol (lval->sym);
583 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
584 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
585 strncpyz (lval->name, buffer, sizeof(lval->name));
586 addSym (SymbolTab, lval->sym, lval->sym->name,
587 lval->sym->level, lval->sym->block, 1);
588 lval->sym->_isparm = 1;
589 addSet (&operKeyReset, lval->sym);
597 /*-----------------------------------------------------------------*/
598 /* allocLocal - allocate local variables */
599 /*-----------------------------------------------------------------*/
601 allocLocal (symbol * sym)
604 /* generate an unique name */
605 SNPRINTF (sym->rname, sizeof(sym->rname),
608 currFunc->name, sym->name, sym->level, sym->block);
611 sym->localof = currFunc;
613 /* if this is a static variable */
614 if (IS_STATIC (sym->etype))
621 /* if volatile then */
622 if (IS_VOLATILE (sym->etype))
625 /* this is automatic */
627 /* if it to be placed on the stack */
628 if (options.stackAuto || reentrant) {
630 if (options.useXstack) {
631 /* PENDING: stack direction for xstack */
632 SPEC_OCLS (sym->etype) = xstack;
633 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
634 xstackPtr += getSize (sym->type);
636 SPEC_OCLS (sym->etype) = istack;
637 if (port->stack.direction > 0) {
638 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
639 stackPtr += getSize (sym->type);
641 stackPtr -= getSize (sym->type);
642 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
649 /* else depending on the storage class specified */
650 if (SPEC_SCLS (sym->etype) == S_XDATA)
652 SPEC_OCLS (sym->etype) = xdata;
657 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
658 SPEC_OCLS (sym->etype) = statsg;
663 if (SPEC_SCLS (sym->etype) == S_IDATA)
665 SPEC_OCLS (sym->etype) = idata;
671 /* if this is a function then assign code space */
672 if (IS_FUNC (sym->type))
674 SPEC_OCLS (sym->etype) = code;
678 /* if this is a SFR or SBIT */
679 if (SPEC_SCLS (sym->etype) == S_SFR ||
680 SPEC_SCLS (sym->etype) == S_SBIT)
683 /* if both absolute address & initial */
684 /* value specified then error */
685 if (IS_ABSOLUTE (sym->etype) && sym->ival)
687 werror (E_SFR_INIT, sym->name);
691 SPEC_OCLS (sym->etype) =
692 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
698 /* if this is a bit variable and no storage class */
699 if (SPEC_NOUN (sym->etype) == V_BIT
700 && (SPEC_SCLS (sym->etype) == S_BIT))
702 SPEC_OCLS (sym->etype) = bit;
707 if (SPEC_SCLS (sym->etype) == S_DATA)
709 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
714 if (SPEC_SCLS (sym->etype) == S_EEPROM)
716 SPEC_OCLS (sym->etype) = eeprom;
721 /* again note that we have put it into the overlay segment
722 will remove and put into the 'data' segment if required after
723 overlay analysis has been done */
724 if (options.model == MODEL_SMALL) {
725 SPEC_OCLS (sym->etype) =
726 (options.noOverlay ? port->mem.default_local_map
729 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
734 /*-----------------------------------------------------------------*/
735 /* deallocLocal - deallocates the local variables */
736 /*-----------------------------------------------------------------*/
738 deallocLocal (symbol * csym)
742 for (sym = csym; sym; sym = sym->next)
747 /* if it is on the stack */
750 if (options.useXstack)
751 xstackPtr -= getSize (sym->type);
753 stackPtr -= getSize (sym->type);
755 /* if not used give a warning */
756 if (!sym->isref && !IS_STATIC (sym->etype))
757 werror (W_NO_REFERENCE, currFunc->name,
758 "local variable", sym->name);
759 /* now delete it from the symbol table */
760 deleteSym (SymbolTab, sym, sym->name);
764 /*-----------------------------------------------------------------*/
765 /* overlay2data - moves declarations from the overlay seg to data */
766 /*-----------------------------------------------------------------*/
772 for (sym = setFirstItem (overlay->syms); sym;
773 sym = setNextItem (overlay->syms))
776 SPEC_OCLS (sym->etype) = data;
780 setToNull ((void **) &overlay->syms);
784 /*-----------------------------------------------------------------*/
785 /* overlay2Set - will add all symbols from the overlay segment to */
786 /* the set of sets containing the overlable symbols */
787 /*-----------------------------------------------------------------*/
794 for (sym = setFirstItem (overlay->syms); sym;
795 sym = setNextItem (overlay->syms))
801 setToNull ((void **) &overlay->syms);
802 addSet (&ovrSetSets, oset);
806 /*-----------------------------------------------------------------*/
807 /* allocVariables - creates decl & assign storage class for a v */
808 /*-----------------------------------------------------------------*/
810 allocVariables (symbol * symChain)
817 /* go thru the symbol chain */
818 for (sym = symChain; sym; sym = sym->next)
821 /* if this is a typedef then add it */
822 /* to the typedef table */
823 if (IS_TYPEDEF (sym->etype))
825 /* check if the typedef already exists */
826 csym = findSym (TypedefTab, NULL, sym->name);
827 if (csym && csym->level == sym->level)
828 werror (E_DUPLICATE_TYPEDEF, sym->name);
830 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
831 continue; /* go to the next one */
833 /* make sure it already exist */
834 csym = findSymWithLevel (SymbolTab, sym);
835 if (!csym || (csym && csym->level != sym->level))
838 /* check the declaration */
841 /* if this is a function or a pointer to function */
842 /* then args processing */
843 if (funcInChain (csym->type))
845 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
846 processFuncArgs (csym);
848 /* if register bank specified then update maxRegBank */
849 if (maxRegBank < FUNC_REGBANK (csym->type))
850 maxRegBank = FUNC_REGBANK (csym->type);
851 /*JCF: Mark the register bank as used*/
852 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
855 /* if this is a extern variable then change the */
856 /* level to zero temporarily */
857 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
859 saveLevel = csym->level;
863 /* if this is a literal then it is an enumerated */
864 /* type so need not allocate it space for it */
865 if (IS_LITERAL (sym->etype))
868 /* generate the actual declaration */
873 stack += getSize (csym->type);
878 /* restore the level */
879 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
880 csym->level = saveLevel;
886 /*-----------------------------------------------------------------*/
887 /* redoStackOffsets :- will reassign the values for stack offsets */
888 /*-----------------------------------------------------------------*/
890 redoStackOffsets (void)
896 /* after register allocation is complete we know
897 which variables will need to be assigned space
898 on the stack. We will eliminate those variables
899 which do not have the allocReq flag thus reducing
901 for (sym = setFirstItem (istack->syms); sym;
902 sym = setNextItem (istack->syms))
905 int size = getSize (sym->type);
906 /* nothing to do with parameters so continue */
907 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
910 if (IS_AGGREGATE (sym->type))
912 if (port->stack.direction > 0)
914 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
920 SPEC_STAK (sym->etype) = sym->stack = sPtr;
925 /* if allocation not required then subtract
926 size from overall stack size & continue */
929 currFunc->stack -= size;
930 SPEC_STAK (currFunc->etype) -= size;
934 if (port->stack.direction > 0)
936 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
942 SPEC_STAK (sym->etype) = sym->stack = sPtr;
946 /* do the same for the external stack */
948 for (sym = setFirstItem (xstack->syms); sym;
949 sym = setNextItem (xstack->syms))
952 int size = getSize (sym->type);
953 /* nothing to do with parameters so continue */
954 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
957 if (IS_AGGREGATE (sym->type))
959 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
964 /* if allocation not required then subtract
965 size from overall stack size & continue */
968 currFunc->xstack -= size;
969 SPEC_STAK (currFunc->etype) -= size;
973 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
977 /* if the debug option is set then output the
978 symbols to the map file */
981 for (sym = setFirstItem (istack->syms); sym;
982 sym = setNextItem (istack->syms))
983 cdbSymbol (sym, cdbFile, FALSE, FALSE);
985 for (sym = setFirstItem (xstack->syms); sym;
986 sym = setNextItem (xstack->syms))
987 cdbSymbol (sym, cdbFile, FALSE, FALSE);
991 /*-----------------------------------------------------------------*/
992 /* printAllocInfoSeg- print the allocation for a given section */
993 /*-----------------------------------------------------------------*/
995 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
1004 for (sym = setFirstItem (map->syms); sym;
1005 sym = setNextItem (map->syms))
1008 if (sym->level == 0)
1010 if (sym->localof != func)
1012 fprintf (of, ";%-25s Allocated to ", sym->name);
1014 /* if assigned to registers */
1015 if (!sym->allocreq && sym->reqv)
1018 sym = OP_SYMBOL (sym->reqv);
1019 fprintf (of, "registers ");
1020 for (i = 0; i < 4 && sym->regs[i]; i++)
1021 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1029 fprintf (of, "stack - offset %d\n", sym->stack);
1033 /* otherwise give rname */
1034 fprintf (of, "in memory with name '%s'\n", sym->rname);
1038 /*-----------------------------------------------------------------*/
1039 /* canOverlayLocals - returns true if the local variables can overlayed */
1040 /*-----------------------------------------------------------------*/
1042 canOverlayLocals (eBBlock ** ebbs, int count)
1045 /* if staticAuto is in effect or the current function
1046 being compiled is reentrant or the overlay segment
1047 is empty or no overlay option is in effect then */
1048 if (options.noOverlay ||
1049 options.stackAuto ||
1051 (IFFUNC_ISREENT (currFunc->type) ||
1052 FUNC_ISISR (currFunc->type))) ||
1053 elementsInSet (overlay->syms) == 0)
1057 /* if this is a forces overlay */
1058 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1060 /* otherwise do thru the blocks and see if there
1061 any function calls if found then return false */
1062 for (i = 0; i < count; i++)
1066 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1068 if (ic->op == CALL) {
1069 sym_link *ftype = operandType(IC_LEFT(ic));
1070 /* builtins only can use overlays */
1071 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1072 } else if (ic->op == PCALL) return FALSE;
1076 /* no function calls found return TRUE */
1080 /*-----------------------------------------------------------------*/
1081 /* doOverlays - move the overlay segment to appropriate location */
1082 /*-----------------------------------------------------------------*/
1084 doOverlays (eBBlock ** ebbs, int count)
1090 /* check if the parameters and local variables
1091 of this function can be put in the overlay segment
1092 This check is essentially to see if the function
1093 calls any other functions if yes then we cannot
1095 if (canOverlayLocals (ebbs, count))
1096 /* if we can then put the parameters &
1097 local variables in the overlay set */
1100 /* otherwise put them into data where
1105 /*-----------------------------------------------------------------*/
1106 /* printAllocInfo - prints allocation information for a function */
1107 /*-----------------------------------------------------------------*/
1109 printAllocInfo (symbol * func, FILE * of)
1114 /* must be called after register allocation is complete */
1115 fprintf (of, ";------------------------------------------------------------\n");
1116 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1117 fprintf (of, ";------------------------------------------------------------\n");
1119 printAllocInfoSeg (xstack, func, of);
1120 printAllocInfoSeg (istack, func, of);
1121 printAllocInfoSeg (code, func, of);
1122 printAllocInfoSeg (data, func, of);
1123 printAllocInfoSeg (xdata, func, of);
1124 printAllocInfoSeg (idata, func, of);
1125 printAllocInfoSeg (sfr, func, of);
1126 printAllocInfoSeg (sfrbit, func, of);
1127 fprintf (of, ";------------------------------------------------------------\n");