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 if (!isinSet (operKeyReset, sym)) {
311 addSet(&operKeyReset, sym);
314 /* if this is a literal e.g. enumerated type */
315 /* put it in the data segment & do nothing */
316 if (IS_LITERAL (sym->etype))
318 SPEC_OCLS (sym->etype) = data;
322 /* if this is a function then assign code space */
323 if (IS_FUNC (sym->type))
325 SPEC_OCLS (sym->etype) = code;
326 /* if this is an interrupt service routine
327 then put it in the interrupt service array */
328 if (FUNC_ISISR (sym->type) && !options.noiv
329 && (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
331 if (interrupts[FUNC_INTNO (sym->type)])
332 werror (E_INT_DEFINED,
333 FUNC_INTNO (sym->type),
334 interrupts[FUNC_INTNO (sym->type)]->name);
336 interrupts[FUNC_INTNO (sym->type)] = sym;
338 /* automagically extend the maximum interrupts */
339 if (FUNC_INTNO (sym->type) >= maxInterrupts)
340 maxInterrupts = FUNC_INTNO (sym->type) + 1;
342 /* if it is not compiler defined */
349 /* if this is a SFR or SBIT */
350 if (SPEC_SCLS (sym->etype) == S_SFR ||
351 SPEC_SCLS (sym->etype) == S_SBIT)
354 SPEC_OCLS (sym->etype) =
355 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
361 /* if this is a bit variable and no storage class */
362 if (SPEC_NOUN (sym->etype) == V_BIT
363 && SPEC_SCLS (sym->etype) == S_BIT)
365 SPEC_OCLS (sym->etype) = bit;
370 /* if bit storage class */
371 if (SPEC_SCLS (sym->etype) == S_SBIT)
373 SPEC_OCLS (sym->etype) = bit;
378 if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
379 /* register storage class ignored changed to FIXED */
380 if (SPEC_SCLS (sym->etype) == S_REGISTER)
381 SPEC_SCLS (sym->etype) = S_FIXED;
383 /* if data specified then */
384 if (SPEC_SCLS (sym->etype) == S_DATA)
386 /* set the output class */
387 SPEC_OCLS (sym->etype) = data;
388 /* generate the symbol */
393 /* if it is fixed, then allocate depending on the */
394 /* current memory model, same for automatics */
395 if (SPEC_SCLS (sym->etype) == S_FIXED ||
396 (TARGET_IS_PIC16 && (SPEC_SCLS (sym->etype) == S_REGISTER) && (sym->level==0)) ||
397 SPEC_SCLS (sym->etype) == S_AUTO) {
398 if (port->mem.default_globl_map != xdata) {
399 /* set the output class */
400 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
401 /* generate the symbol */
405 SPEC_SCLS (sym->etype) = S_XDATA;
409 /* if code change to constant */
410 if (SPEC_SCLS (sym->etype) == S_CODE) {
411 SPEC_OCLS (sym->etype) = statsg;
416 if (SPEC_SCLS (sym->etype) == S_XDATA)
418 // should we move this to the initialized data segment?
419 if (port->genXINIT &&
420 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
421 SPEC_OCLS(sym->etype)=xidata;
423 SPEC_OCLS (sym->etype) = xdata;
429 if (SPEC_SCLS (sym->etype) == S_IDATA)
431 SPEC_OCLS (sym->etype) = idata;
437 if (SPEC_SCLS (sym->etype) == S_EEPROM)
439 SPEC_OCLS (sym->etype) = eeprom;
447 /*-----------------------------------------------------------------*/
448 /* allocParms - parameters are always passed on stack */
449 /*-----------------------------------------------------------------*/
451 allocParms (value * val)
456 for (lval = val; lval; lval = lval->next, pNum++)
459 /* check the declaration */
460 checkDecl (lval->sym, 0);
462 /* if this a register parm then allocate
463 it as a local variable by adding it
464 to the first block we see in the body */
465 if (IS_REGPARM (lval->etype))
468 /* mark it as my parameter */
469 lval->sym->ismyparm = 1;
470 lval->sym->localof = currFunc;
473 /* if automatic variables r 2b stacked */
474 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
478 lval->sym->onStack = 1;
480 /* choose which stack 2 use */
481 /* use xternal stack */
482 if (options.useXstack)
484 /* PENDING: stack direction support */
485 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
486 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
487 xstackPtr - getSize (lval->type);
488 xstackPtr -= getSize (lval->type);
491 { /* use internal stack */
492 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
493 if (port->stack.direction > 0)
495 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
496 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
497 getSize (lval->type) -
498 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
499 stackPtr -= getSize (lval->type);
503 /* This looks like the wrong order but it turns out OK... */
504 /* PENDING: isr, bank overhead, ... */
505 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
507 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
508 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
510 stackPtr += getSize (lval->type);
513 allocIntoSeg (lval->sym);
516 { /* allocate them in the automatic space */
517 /* generate a unique name */
518 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
519 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
520 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
522 /* if declared in external storage */
523 if (SPEC_SCLS (lval->etype) == S_XDATA)
524 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
526 /* other wise depending on the memory model
527 note here that we put it into the overlay segment
528 first, we will remove it from the overlay segment
529 after the overlay determination has been done */
530 if (options.model == MODEL_SMALL)
532 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
533 (options.noOverlay ? port->mem.default_local_map
538 SPEC_SCLS (lval->etype) = S_XDATA;
539 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
541 allocIntoSeg (lval->sym);
548 /*-----------------------------------------------------------------*/
549 /* deallocParms - parameters are always passed on stack */
550 /*-----------------------------------------------------------------*/
552 deallocParms (value * val)
556 for (lval = val; lval; lval = lval->next)
559 /* unmark is myparm */
560 lval->sym->ismyparm = 0;
562 /* delete it from the symbol table */
563 deleteSym (SymbolTab, lval->sym, lval->sym->name);
565 if (!lval->sym->isref)
567 lval->sym->allocreq = 0;
568 werror (W_NO_REFERENCE,
569 currFunc ? currFunc->name : "(unknown)",
570 "function argument", lval->sym->name);
573 /* move the rname if any to the name for both val & sym */
574 /* and leave a copy of it in the symbol table */
575 if (lval->sym->rname[0])
577 char buffer[SDCC_NAME_MAX];
578 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
579 lval->sym = copySymbol (lval->sym);
580 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
581 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
582 strncpyz (lval->name, buffer, sizeof(lval->name));
583 addSym (SymbolTab, lval->sym, lval->sym->name,
584 lval->sym->level, lval->sym->block, 1);
585 lval->sym->_isparm = 1;
586 if (!isinSet (operKeyReset, lval->sym)) {
587 addSet(&operKeyReset, lval->sym);
596 /*-----------------------------------------------------------------*/
597 /* allocLocal - allocate local variables */
598 /*-----------------------------------------------------------------*/
600 allocLocal (symbol * sym)
603 /* generate an unique name */
604 SNPRINTF (sym->rname, sizeof(sym->rname),
607 currFunc->name, sym->name, sym->level, sym->block);
610 sym->localof = currFunc;
612 /* if this is a static variable */
613 if (IS_STATIC (sym->etype))
620 /* if volatile then */
621 if (IS_VOLATILE (sym->etype))
624 /* this is automatic */
626 /* if it to be placed on the stack */
627 if (options.stackAuto || reentrant) {
629 if (options.useXstack) {
630 /* PENDING: stack direction for xstack */
631 SPEC_OCLS (sym->etype) = xstack;
632 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
633 xstackPtr += getSize (sym->type);
635 SPEC_OCLS (sym->etype) = istack;
636 if (port->stack.direction > 0) {
637 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
638 stackPtr += getSize (sym->type);
640 stackPtr -= getSize (sym->type);
641 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
648 /* else depending on the storage class specified */
649 if (SPEC_SCLS (sym->etype) == S_XDATA)
651 SPEC_OCLS (sym->etype) = xdata;
656 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
657 SPEC_OCLS (sym->etype) = statsg;
662 if (SPEC_SCLS (sym->etype) == S_IDATA)
664 SPEC_OCLS (sym->etype) = idata;
670 /* if this is a function then assign code space */
671 if (IS_FUNC (sym->type))
673 SPEC_OCLS (sym->etype) = code;
677 /* if this is a SFR or SBIT */
678 if (SPEC_SCLS (sym->etype) == S_SFR ||
679 SPEC_SCLS (sym->etype) == S_SBIT)
681 SPEC_OCLS (sym->etype) =
682 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
688 /* if this is a bit variable and no storage class */
689 if (SPEC_NOUN (sym->etype) == V_BIT
690 && (SPEC_SCLS (sym->etype) == S_BIT))
692 SPEC_OCLS (sym->etype) = bit;
697 if (SPEC_SCLS (sym->etype) == S_DATA)
699 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
704 if (SPEC_SCLS (sym->etype) == S_EEPROM)
706 SPEC_OCLS (sym->etype) = eeprom;
711 /* again note that we have put it into the overlay segment
712 will remove and put into the 'data' segment if required after
713 overlay analysis has been done */
714 if (options.model == MODEL_SMALL) {
715 SPEC_OCLS (sym->etype) =
716 (options.noOverlay ? port->mem.default_local_map
719 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
724 /*-----------------------------------------------------------------*/
725 /* deallocLocal - deallocates the local variables */
726 /*-----------------------------------------------------------------*/
728 deallocLocal (symbol * csym)
732 for (sym = csym; sym; sym = sym->next)
737 /* if it is on the stack */
740 if (options.useXstack)
741 xstackPtr -= getSize (sym->type);
743 stackPtr -= getSize (sym->type);
745 /* if not used give a warning */
746 if (!sym->isref && !IS_STATIC (sym->etype))
747 werror (W_NO_REFERENCE,
748 currFunc ? currFunc->name : "(unknown)",
749 "local variable", sym->name);
750 /* now delete it from the symbol table */
751 deleteSym (SymbolTab, sym, sym->name);
755 /*-----------------------------------------------------------------*/
756 /* overlay2data - moves declarations from the overlay seg to data */
757 /*-----------------------------------------------------------------*/
763 for (sym = setFirstItem (overlay->syms); sym;
764 sym = setNextItem (overlay->syms))
767 SPEC_OCLS (sym->etype) = data;
771 setToNull ((void *) &overlay->syms);
775 /*-----------------------------------------------------------------*/
776 /* overlay2Set - will add all symbols from the overlay segment to */
777 /* the set of sets containing the overlable symbols */
778 /*-----------------------------------------------------------------*/
785 for (sym = setFirstItem (overlay->syms); sym;
786 sym = setNextItem (overlay->syms))
792 setToNull ((void *) &overlay->syms);
793 addSet (&ovrSetSets, oset);
797 /*-----------------------------------------------------------------*/
798 /* allocVariables - creates decl & assign storage class for a v */
799 /*-----------------------------------------------------------------*/
801 allocVariables (symbol * symChain)
808 /* go thru the symbol chain */
809 for (sym = symChain; sym; sym = sym->next)
812 /* if this is a typedef then add it */
813 /* to the typedef table */
814 if (IS_TYPEDEF (sym->etype))
816 /* check if the typedef already exists */
817 csym = findSym (TypedefTab, NULL, sym->name);
818 if (csym && csym->level == sym->level)
819 werror (E_DUPLICATE_TYPEDEF, sym->name);
821 SPEC_EXTR (sym->etype) = 0;
822 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
823 continue; /* go to the next one */
825 /* make sure it already exist */
826 csym = findSymWithLevel (SymbolTab, sym);
827 if (!csym || (csym && csym->level != sym->level))
830 /* check the declaration */
833 /* if this is a function or a pointer to function */
834 /* then args processing */
835 if (funcInChain (csym->type))
837 processFuncArgs (csym);
839 /* if register bank specified then update maxRegBank */
840 if (maxRegBank < FUNC_REGBANK (csym->type))
841 maxRegBank = FUNC_REGBANK (csym->type);
842 /*JCF: Mark the register bank as used*/
843 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
846 /* if this is a extern variable then change the */
847 /* level to zero temporarily */
848 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
850 saveLevel = csym->level;
854 /* if this is a literal then it is an enumerated */
855 /* type so need not allocate it space for it */
856 if (IS_LITERAL (sym->etype))
859 /* generate the actual declaration */
864 stack += getSize (csym->type);
869 /* restore the level */
870 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
871 csym->level = saveLevel;
877 /*-----------------------------------------------------------------*/
878 /* redoStackOffsets :- will reassign the values for stack offsets */
879 /*-----------------------------------------------------------------*/
881 redoStackOffsets (void)
887 /* after register allocation is complete we know
888 which variables will need to be assigned space
889 on the stack. We will eliminate those variables
890 which do not have the allocReq flag thus reducing
892 for (sym = setFirstItem (istack->syms); sym;
893 sym = setNextItem (istack->syms))
896 int size = getSize (sym->type);
897 /* nothing to do with parameters so continue */
898 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
901 if (IS_AGGREGATE (sym->type))
903 if (port->stack.direction > 0)
905 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
911 SPEC_STAK (sym->etype) = sym->stack = sPtr;
916 /* if allocation not required then subtract
917 size from overall stack size & continue */
920 currFunc->stack -= size;
921 SPEC_STAK (currFunc->etype) -= size;
925 if (port->stack.direction > 0)
927 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
933 SPEC_STAK (sym->etype) = sym->stack = sPtr;
937 /* do the same for the external stack */
939 for (sym = setFirstItem (xstack->syms); sym;
940 sym = setNextItem (xstack->syms))
943 int size = getSize (sym->type);
944 /* nothing to do with parameters so continue */
945 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
948 if (IS_AGGREGATE (sym->type))
950 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
955 /* if allocation not required then subtract
956 size from overall stack size & continue */
959 currFunc->xstack -= size;
960 SPEC_STAK (currFunc->etype) -= size;
964 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
970 /*-----------------------------------------------------------------*/
971 /* printAllocInfoSeg- print the allocation for a given section */
972 /*-----------------------------------------------------------------*/
974 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
983 for (sym = setFirstItem (map->syms); sym;
984 sym = setNextItem (map->syms))
989 if (sym->localof != func)
992 fprintf (of, ";%-25s Allocated ", sym->name);
994 /* if assigned to registers */
995 if (!sym->allocreq && sym->reqv)
999 sym = OP_SYMBOL (sym->reqv);
1000 if (!sym->isspilt || sym->remat)
1002 fprintf (of, "to registers ");
1003 for (i = 0; i < 4 && sym->regs[i]; i++)
1004 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1010 sym = sym->usl.spillLoc;
1017 fprintf (of, "to stack - offset %d\n", sym->stack);
1021 /* otherwise give rname */
1022 fprintf (of, "with name '%s'\n", sym->rname);
1026 /*-----------------------------------------------------------------*/
1027 /* canOverlayLocals - returns true if the local variables can overlayed */
1028 /*-----------------------------------------------------------------*/
1030 canOverlayLocals (eBBlock ** ebbs, int count)
1033 /* if staticAuto is in effect or the current function
1034 being compiled is reentrant or the overlay segment
1035 is empty or no overlay option is in effect then */
1036 if (options.noOverlay ||
1037 options.stackAuto ||
1039 (IFFUNC_ISREENT (currFunc->type) ||
1040 FUNC_ISISR (currFunc->type))) ||
1041 elementsInSet (overlay->syms) == 0)
1045 /* if this is a forces overlay */
1046 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1048 /* otherwise do thru the blocks and see if there
1049 any function calls if found then return false */
1050 for (i = 0; i < count; i++)
1054 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1056 if (ic->op == CALL) {
1057 sym_link *ftype = operandType(IC_LEFT(ic));
1058 /* builtins only can use overlays */
1059 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1060 } else if (ic->op == PCALL) return FALSE;
1064 /* no function calls found return TRUE */
1068 /*-----------------------------------------------------------------*/
1069 /* doOverlays - move the overlay segment to appropriate location */
1070 /*-----------------------------------------------------------------*/
1072 doOverlays (eBBlock ** ebbs, int count)
1078 /* check if the parameters and local variables
1079 of this function can be put in the overlay segment
1080 This check is essentially to see if the function
1081 calls any other functions if yes then we cannot
1083 if (canOverlayLocals (ebbs, count))
1084 /* if we can then put the parameters &
1085 local variables in the overlay set */
1088 /* otherwise put them into data where
1093 /*-----------------------------------------------------------------*/
1094 /* printAllocInfo - prints allocation information for a function */
1095 /*-----------------------------------------------------------------*/
1097 printAllocInfo (symbol * func, FILE * of)
1105 /* must be called after register allocation is complete */
1106 fprintf (of, ";------------------------------------------------------------\n");
1107 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1108 fprintf (of, ";------------------------------------------------------------\n");
1110 printAllocInfoSeg (xstack, func, of);
1111 printAllocInfoSeg (istack, func, of);
1112 printAllocInfoSeg (code, func, of);
1113 printAllocInfoSeg (data, func, of);
1114 printAllocInfoSeg (xdata, func, of);
1115 printAllocInfoSeg (idata, func, of);
1116 printAllocInfoSeg (sfr, func, of);
1117 printAllocInfoSeg (sfrbit, func, of);
1121 set *tempOverlaySyms = overlay->syms;
1123 /* search the set of overlay sets for local variables/parameters */
1124 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1125 ovrset = setNextItem (ovrSetSets))
1127 overlay->syms = ovrset;
1128 printAllocInfoSeg (overlay, func, of);
1130 overlay->syms = tempOverlaySyms;
1133 fprintf (of, ";------------------------------------------------------------\n");