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 sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name);
308 /* add it to the operandKey reset */
309 addSet (&operKeyReset, sym);
311 /* if this is a literal e.g. enumerated type */
312 /* put it in the data segment & do nothing */
313 if (IS_LITERAL (sym->etype))
315 SPEC_OCLS (sym->etype) = data;
319 /* if this is a function then assign code space */
320 if (IS_FUNC (sym->type))
322 SPEC_OCLS (sym->etype) = code;
323 /* if this is an interrupt service routine
324 then put it in the interrupt service array */
325 if (FUNC_ISISR (sym->type) && !options.noiv)
328 if (interrupts[FUNC_INTNO (sym->type)])
329 werror (E_INT_DEFINED,
330 FUNC_INTNO (sym->type),
331 interrupts[FUNC_INTNO (sym->type)]->name);
333 interrupts[FUNC_INTNO (sym->type)] = sym;
335 /* automagically extend the maximum interrupts */
336 if (FUNC_INTNO (sym->type) >= maxInterrupts)
337 maxInterrupts = FUNC_INTNO (sym->type) + 1;
339 /* if it is not compiler defined */
346 /* if this is a SFR or SBIT */
347 if (SPEC_SCLS (sym->etype) == S_SFR ||
348 SPEC_SCLS (sym->etype) == S_SBIT)
351 /* if both absolute address & initial */
352 /* value specified then error */
353 if (IS_ABSOLUTE (sym->etype) && sym->ival)
355 werror (E_SFR_INIT, sym->name);
359 SPEC_OCLS (sym->etype) =
360 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
366 /* if this is a bit variable and no storage class */
367 if (SPEC_NOUN (sym->etype) == V_BIT
368 && SPEC_SCLS (sym->etype) == S_BIT)
370 SPEC_OCLS (sym->etype) = bit;
375 /* if bit storage class */
376 if (SPEC_SCLS (sym->etype) == S_SBIT)
378 SPEC_OCLS (sym->etype) = bit;
383 /* register storage class ignored changed to FIXED */
384 if (SPEC_SCLS (sym->etype) == S_REGISTER)
385 SPEC_SCLS (sym->etype) = S_FIXED;
387 /* if data specified then */
388 if (SPEC_SCLS (sym->etype) == S_DATA)
390 /* set the output class */
391 SPEC_OCLS (sym->etype) = data;
392 /* generate the symbol */
397 /* if it is fixed, then allocate depending on the */
398 /* current memory model, same for automatics */
399 if (SPEC_SCLS (sym->etype) == S_FIXED ||
400 SPEC_SCLS (sym->etype) == S_AUTO) {
401 if (port->mem.default_globl_map != xdata) {
402 /* set the output class */
403 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
404 /* generate the symbol */
408 SPEC_SCLS (sym->etype) = S_XDATA;
412 /* if code change to constant */
413 if (SPEC_SCLS (sym->etype) == S_CODE) {
414 SPEC_OCLS (sym->etype) = statsg;
419 if (SPEC_SCLS (sym->etype) == S_XDATA)
421 // should we move this to the initialized data segment?
422 if (port->genXINIT &&
423 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
424 SPEC_OCLS(sym->etype)=xidata;
426 SPEC_OCLS (sym->etype) = xdata;
432 if (SPEC_SCLS (sym->etype) == S_IDATA)
434 SPEC_OCLS (sym->etype) = idata;
440 if (SPEC_SCLS (sym->etype) == S_EEPROM)
442 SPEC_OCLS (sym->etype) = eeprom;
450 /*-----------------------------------------------------------------*/
451 /* allocParms - parameters are always passed on stack */
452 /*-----------------------------------------------------------------*/
454 allocParms (value * val)
459 for (lval = val; lval; lval = lval->next, pNum++)
462 /* check the declaration */
463 checkDecl (lval->sym, 0);
465 /* if this a register parm then allocate
466 it as a local variable by adding it
467 to the first block we see in the body */
468 if (IS_REGPARM (lval->etype))
471 /* mark it as my parameter */
472 lval->sym->ismyparm = 1;
473 lval->sym->localof = currFunc;
476 /* if automatic variables r 2b stacked */
477 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
481 lval->sym->onStack = 1;
483 /* choose which stack 2 use */
484 /* use xternal stack */
485 if (options.useXstack)
487 /* PENDING: stack direction support */
488 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
489 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
490 xstackPtr - getSize (lval->type);
491 xstackPtr -= getSize (lval->type);
494 { /* use internal stack */
495 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
496 if (port->stack.direction > 0)
498 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
499 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
500 getSize (lval->type) -
501 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
502 stackPtr -= getSize (lval->type);
506 /* This looks like the wrong order but it turns out OK... */
507 /* PENDING: isr, bank overhead, ... */
508 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
510 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
511 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
513 stackPtr += getSize (lval->type);
516 allocIntoSeg (lval->sym);
519 { /* allocate them in the automatic space */
520 /* generate a unique name */
521 sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
522 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
524 /* if declared in external storage */
525 if (SPEC_SCLS (lval->etype) == S_XDATA)
526 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
528 /* other wise depending on the memory model
529 note here that we put it into the overlay segment
530 first, we will remove it from the overlay segment
531 after the overlay determination has been done */
532 if (options.model == MODEL_SMALL)
534 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
535 (options.noOverlay ? port->mem.default_local_map
540 SPEC_SCLS (lval->etype) = S_XDATA;
541 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
543 allocIntoSeg (lval->sym);
550 /*-----------------------------------------------------------------*/
551 /* deallocParms - parameters are always passed on stack */
552 /*-----------------------------------------------------------------*/
554 deallocParms (value * val)
558 for (lval = val; lval; lval = lval->next)
561 /* unmark is myparm */
562 lval->sym->ismyparm = 0;
564 /* delete it from the symbol table */
565 deleteSym (SymbolTab, lval->sym, lval->sym->name);
567 if (!lval->sym->isref)
569 lval->sym->allocreq = 0;
570 werror (W_NO_REFERENCE, currFunc->name,
571 "function argument", lval->sym->name);
574 /* move the rname if any to the name for both val & sym */
575 /* and leave a copy of it in the symbol table */
576 if (lval->sym->rname[0])
578 char buffer[SDCC_NAME_MAX];
579 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
580 lval->sym = copySymbol (lval->sym);
581 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
582 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
583 strncpyz (lval->name, buffer, sizeof(lval->name));
584 addSym (SymbolTab, lval->sym, lval->sym->name,
585 lval->sym->level, lval->sym->block, 1);
586 lval->sym->_isparm = 1;
587 addSet (&operKeyReset, lval->sym);
595 /*-----------------------------------------------------------------*/
596 /* allocLocal - allocate local variables */
597 /*-----------------------------------------------------------------*/
599 allocLocal (symbol * sym)
602 /* generate an unique name */
603 sprintf (sym->rname, "%s%s_%s_%d_%d",
605 currFunc->name, sym->name, sym->level, sym->block);
608 sym->localof = currFunc;
610 /* if this is a static variable */
611 if (IS_STATIC (sym->etype))
618 /* if volatile then */
619 if (IS_VOLATILE (sym->etype))
622 /* this is automatic */
624 /* if it to be placed on the stack */
625 if (options.stackAuto || reentrant) {
627 if (options.useXstack) {
628 /* PENDING: stack direction for xstack */
629 SPEC_OCLS (sym->etype) = xstack;
630 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
631 xstackPtr += getSize (sym->type);
633 SPEC_OCLS (sym->etype) = istack;
634 if (port->stack.direction > 0) {
635 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
636 stackPtr += getSize (sym->type);
638 stackPtr -= getSize (sym->type);
639 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
646 /* else depending on the storage class specified */
647 if (SPEC_SCLS (sym->etype) == S_XDATA)
649 SPEC_OCLS (sym->etype) = xdata;
654 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
655 SPEC_OCLS (sym->etype) = statsg;
660 if (SPEC_SCLS (sym->etype) == S_IDATA)
662 SPEC_OCLS (sym->etype) = idata;
668 /* if this is a function then assign code space */
669 if (IS_FUNC (sym->type))
671 SPEC_OCLS (sym->etype) = code;
675 /* if this is a SFR or SBIT */
676 if (SPEC_SCLS (sym->etype) == S_SFR ||
677 SPEC_SCLS (sym->etype) == S_SBIT)
680 /* if both absolute address & initial */
681 /* value specified then error */
682 if (IS_ABSOLUTE (sym->etype) && sym->ival)
684 werror (E_SFR_INIT, sym->name);
688 SPEC_OCLS (sym->etype) =
689 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
695 /* if this is a bit variable and no storage class */
696 if (SPEC_NOUN (sym->etype) == V_BIT
697 && (SPEC_SCLS (sym->etype) == S_BIT))
699 SPEC_OCLS (sym->etype) = bit;
704 if (SPEC_SCLS (sym->etype) == S_DATA)
706 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
711 if (SPEC_SCLS (sym->etype) == S_EEPROM)
713 SPEC_OCLS (sym->etype) = eeprom;
718 /* again note that we have put it into the overlay segment
719 will remove and put into the 'data' segment if required after
720 overlay analysis has been done */
721 if (options.model == MODEL_SMALL) {
722 SPEC_OCLS (sym->etype) =
723 (options.noOverlay ? port->mem.default_local_map
726 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
731 /*-----------------------------------------------------------------*/
732 /* deallocLocal - deallocates the local variables */
733 /*-----------------------------------------------------------------*/
735 deallocLocal (symbol * csym)
739 for (sym = csym; sym; sym = sym->next)
744 /* if it is on the stack */
747 if (options.useXstack)
748 xstackPtr -= getSize (sym->type);
750 stackPtr -= getSize (sym->type);
752 /* if not used give a warning */
753 if (!sym->isref && !IS_STATIC (sym->etype))
754 werror (W_NO_REFERENCE, currFunc->name,
755 "local variable", sym->name);
756 /* now delete it from the symbol table */
757 deleteSym (SymbolTab, sym, sym->name);
761 /*-----------------------------------------------------------------*/
762 /* overlay2data - moves declarations from the overlay seg to data */
763 /*-----------------------------------------------------------------*/
769 for (sym = setFirstItem (overlay->syms); sym;
770 sym = setNextItem (overlay->syms))
773 SPEC_OCLS (sym->etype) = data;
777 setToNull ((void **) &overlay->syms);
781 /*-----------------------------------------------------------------*/
782 /* overlay2Set - will add all symbols from the overlay segment to */
783 /* the set of sets containing the overlable symbols */
784 /*-----------------------------------------------------------------*/
791 for (sym = setFirstItem (overlay->syms); sym;
792 sym = setNextItem (overlay->syms))
798 setToNull ((void **) &overlay->syms);
799 addSet (&ovrSetSets, oset);
803 /*-----------------------------------------------------------------*/
804 /* allocVariables - creates decl & assign storage class for a v */
805 /*-----------------------------------------------------------------*/
807 allocVariables (symbol * symChain)
814 /* go thru the symbol chain */
815 for (sym = symChain; sym; sym = sym->next)
818 /* if this is a typedef then add it */
819 /* to the typedef table */
820 if (IS_TYPEDEF (sym->etype))
822 /* check if the typedef already exists */
823 csym = findSym (TypedefTab, NULL, sym->name);
824 if (csym && csym->level == sym->level)
825 werror (E_DUPLICATE_TYPEDEF, sym->name);
827 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
828 continue; /* go to the next one */
830 /* make sure it already exist */
831 csym = findSymWithLevel (SymbolTab, sym);
832 if (!csym || (csym && csym->level != sym->level))
835 /* check the declaration */
838 /* if this is a function or a pointer to function */
839 /* then args processing */
840 if (funcInChain (csym->type))
842 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
843 processFuncArgs (csym);
845 /* if register bank specified then update maxRegBank */
846 if (maxRegBank < FUNC_REGBANK (csym->type))
847 maxRegBank = FUNC_REGBANK (csym->type);
848 /*JCF: Mark the register bank as used*/
849 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
852 /* if this is a extern variable then change the */
853 /* level to zero temporarily */
854 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
856 saveLevel = csym->level;
860 /* if this is a literal then it is an enumerated */
861 /* type so need not allocate it space for it */
862 if (IS_LITERAL (sym->etype))
865 /* generate the actual declaration */
870 stack += getSize (csym->type);
875 /* restore the level */
876 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
877 csym->level = saveLevel;
883 /*-----------------------------------------------------------------*/
884 /* redoStackOffsets :- will reassign the values for stack offsets */
885 /*-----------------------------------------------------------------*/
887 redoStackOffsets (void)
893 /* after register allocation is complete we know
894 which variables will need to be assigned space
895 on the stack. We will eliminate those variables
896 which do not have the allocReq flag thus reducing
898 for (sym = setFirstItem (istack->syms); sym;
899 sym = setNextItem (istack->syms))
902 int size = getSize (sym->type);
903 /* nothing to do with parameters so continue */
904 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
907 if (IS_AGGREGATE (sym->type))
909 if (port->stack.direction > 0)
911 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
917 SPEC_STAK (sym->etype) = sym->stack = sPtr;
922 /* if allocation not required then subtract
923 size from overall stack size & continue */
926 currFunc->stack -= size;
927 SPEC_STAK (currFunc->etype) -= size;
931 if (port->stack.direction > 0)
933 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
939 SPEC_STAK (sym->etype) = sym->stack = sPtr;
943 /* do the same for the external stack */
945 for (sym = setFirstItem (xstack->syms); sym;
946 sym = setNextItem (xstack->syms))
949 int size = getSize (sym->type);
950 /* nothing to do with parameters so continue */
951 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
954 if (IS_AGGREGATE (sym->type))
956 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
961 /* if allocation not required then subtract
962 size from overall stack size & continue */
965 currFunc->xstack -= size;
966 SPEC_STAK (currFunc->etype) -= size;
970 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
974 /* if the debug option is set then output the
975 symbols to the map file */
978 for (sym = setFirstItem (istack->syms); sym;
979 sym = setNextItem (istack->syms))
980 cdbSymbol (sym, cdbFile, FALSE, FALSE);
982 for (sym = setFirstItem (xstack->syms); sym;
983 sym = setNextItem (xstack->syms))
984 cdbSymbol (sym, cdbFile, FALSE, FALSE);
988 /*-----------------------------------------------------------------*/
989 /* printAllocInfoSeg- print the allocation for a given section */
990 /*-----------------------------------------------------------------*/
992 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
1001 for (sym = setFirstItem (map->syms); sym;
1002 sym = setNextItem (map->syms))
1005 if (sym->level == 0)
1007 if (sym->localof != func)
1009 fprintf (of, ";%-25s Allocated to ", sym->name);
1011 /* if assigned to registers */
1012 if (!sym->allocreq && sym->reqv)
1015 sym = OP_SYMBOL (sym->reqv);
1016 fprintf (of, "registers ");
1017 for (i = 0; i < 4 && sym->regs[i]; i++)
1018 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1026 fprintf (of, "stack - offset %d\n", sym->stack);
1030 /* otherwise give rname */
1031 fprintf (of, "in memory with name '%s'\n", sym->rname);
1035 /*-----------------------------------------------------------------*/
1036 /* canOverlayLocals - returns true if the local variables can overlayed */
1037 /*-----------------------------------------------------------------*/
1039 canOverlayLocals (eBBlock ** ebbs, int count)
1042 /* if staticAuto is in effect or the current function
1043 being compiled is reentrant or the overlay segment
1044 is empty or no overlay option is in effect then */
1045 if (options.noOverlay ||
1046 options.stackAuto ||
1048 (IFFUNC_ISREENT (currFunc->type) ||
1049 FUNC_ISISR (currFunc->type))) ||
1050 elementsInSet (overlay->syms) == 0)
1054 /* if this is a forces overlay */
1055 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1057 /* otherwise do thru the blocks and see if there
1058 any function calls if found then return false */
1059 for (i = 0; i < count; i++)
1063 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1065 if (ic->op == CALL) {
1066 sym_link *ftype = operandType(IC_LEFT(ic));
1067 /* builtins only can use overlays */
1068 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1069 } else if (ic->op == PCALL) return FALSE;
1073 /* no function calls found return TRUE */
1077 /*-----------------------------------------------------------------*/
1078 /* doOverlays - move the overlay segment to appropriate location */
1079 /*-----------------------------------------------------------------*/
1081 doOverlays (eBBlock ** ebbs, int count)
1087 /* check if the parameters and local variables
1088 of this function can be put in the overlay segment
1089 This check is essentially to see if the function
1090 calls any other functions if yes then we cannot
1092 if (canOverlayLocals (ebbs, count))
1093 /* if we can then put the parameters &
1094 local variables in the overlay set */
1097 /* otherwise put them into data where
1102 /*-----------------------------------------------------------------*/
1103 /* printAllocInfo - prints allocation information for a function */
1104 /*-----------------------------------------------------------------*/
1106 printAllocInfo (symbol * func, FILE * of)
1111 /* must be called after register allocation is complete */
1112 fprintf (of, ";------------------------------------------------------------\n");
1113 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1114 fprintf (of, ";------------------------------------------------------------\n");
1116 printAllocInfoSeg (xstack, func, of);
1117 printAllocInfoSeg (istack, func, of);
1118 printAllocInfoSeg (code, func, of);
1119 printAllocInfoSeg (data, func, of);
1120 printAllocInfoSeg (xdata, func, of);
1121 printAllocInfoSeg (idata, func, of);
1122 printAllocInfoSeg (sfr, func, of);
1123 printAllocInfoSeg (sfrbit, func, of);
1124 fprintf (of, ";------------------------------------------------------------\n");