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 /* register storage class ignored changed to FIXED */
379 if (SPEC_SCLS (sym->etype) == S_REGISTER)
380 SPEC_SCLS (sym->etype) = S_FIXED;
382 /* if data specified then */
383 if (SPEC_SCLS (sym->etype) == S_DATA)
385 /* set the output class */
386 SPEC_OCLS (sym->etype) = data;
387 /* generate the symbol */
392 /* if it is fixed, then allocate depending on the */
393 /* current memory model, same for automatics */
394 if (SPEC_SCLS (sym->etype) == S_FIXED ||
395 SPEC_SCLS (sym->etype) == S_AUTO) {
396 if (port->mem.default_globl_map != xdata) {
397 /* set the output class */
398 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
399 /* generate the symbol */
403 SPEC_SCLS (sym->etype) = S_XDATA;
407 /* if code change to constant */
408 if (SPEC_SCLS (sym->etype) == S_CODE) {
409 SPEC_OCLS (sym->etype) = statsg;
414 if (SPEC_SCLS (sym->etype) == S_XDATA)
416 // should we move this to the initialized data segment?
417 if (port->genXINIT &&
418 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
419 SPEC_OCLS(sym->etype)=xidata;
421 SPEC_OCLS (sym->etype) = xdata;
427 if (SPEC_SCLS (sym->etype) == S_IDATA)
429 SPEC_OCLS (sym->etype) = idata;
435 if (SPEC_SCLS (sym->etype) == S_EEPROM)
437 SPEC_OCLS (sym->etype) = eeprom;
445 /*-----------------------------------------------------------------*/
446 /* allocParms - parameters are always passed on stack */
447 /*-----------------------------------------------------------------*/
449 allocParms (value * val)
454 for (lval = val; lval; lval = lval->next, pNum++)
457 /* check the declaration */
458 checkDecl (lval->sym, 0);
460 /* if this a register parm then allocate
461 it as a local variable by adding it
462 to the first block we see in the body */
463 if (IS_REGPARM (lval->etype))
466 /* mark it as my parameter */
467 lval->sym->ismyparm = 1;
468 lval->sym->localof = currFunc;
471 /* if automatic variables r 2b stacked */
472 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
476 lval->sym->onStack = 1;
478 /* choose which stack 2 use */
479 /* use xternal stack */
480 if (options.useXstack)
482 /* PENDING: stack direction support */
483 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
484 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
485 xstackPtr - getSize (lval->type);
486 xstackPtr -= getSize (lval->type);
489 { /* use internal stack */
490 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
491 if (port->stack.direction > 0)
493 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
494 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
495 getSize (lval->type) -
496 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
497 stackPtr -= getSize (lval->type);
501 /* This looks like the wrong order but it turns out OK... */
502 /* PENDING: isr, bank overhead, ... */
503 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
505 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
506 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
508 stackPtr += getSize (lval->type);
511 allocIntoSeg (lval->sym);
514 { /* allocate them in the automatic space */
515 /* generate a unique name */
516 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
517 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
518 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
520 /* if declared in external storage */
521 if (SPEC_SCLS (lval->etype) == S_XDATA)
522 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
524 /* other wise depending on the memory model
525 note here that we put it into the overlay segment
526 first, we will remove it from the overlay segment
527 after the overlay determination has been done */
528 if (options.model == MODEL_SMALL)
530 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
531 (options.noOverlay ? port->mem.default_local_map
536 SPEC_SCLS (lval->etype) = S_XDATA;
537 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
539 allocIntoSeg (lval->sym);
546 /*-----------------------------------------------------------------*/
547 /* deallocParms - parameters are always passed on stack */
548 /*-----------------------------------------------------------------*/
550 deallocParms (value * val)
554 for (lval = val; lval; lval = lval->next)
557 /* unmark is myparm */
558 lval->sym->ismyparm = 0;
560 /* delete it from the symbol table */
561 deleteSym (SymbolTab, lval->sym, lval->sym->name);
563 if (!lval->sym->isref)
565 lval->sym->allocreq = 0;
566 werror (W_NO_REFERENCE,
567 currFunc ? currFunc->name : "(unknown)",
568 "function argument", lval->sym->name);
571 /* move the rname if any to the name for both val & sym */
572 /* and leave a copy of it in the symbol table */
573 if (lval->sym->rname[0])
575 char buffer[SDCC_NAME_MAX];
576 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
577 lval->sym = copySymbol (lval->sym);
578 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
579 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
580 strncpyz (lval->name, buffer, sizeof(lval->name));
581 addSym (SymbolTab, lval->sym, lval->sym->name,
582 lval->sym->level, lval->sym->block, 1);
583 lval->sym->_isparm = 1;
584 if (!isinSet (operKeyReset, lval->sym)) {
585 addSet(&operKeyReset, lval->sym);
594 /*-----------------------------------------------------------------*/
595 /* allocLocal - allocate local variables */
596 /*-----------------------------------------------------------------*/
598 allocLocal (symbol * sym)
601 /* generate an unique name */
602 SNPRINTF (sym->rname, sizeof(sym->rname),
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)
679 SPEC_OCLS (sym->etype) =
680 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
686 /* if this is a bit variable and no storage class */
687 if (SPEC_NOUN (sym->etype) == V_BIT
688 && (SPEC_SCLS (sym->etype) == S_BIT))
690 SPEC_OCLS (sym->etype) = bit;
695 if (SPEC_SCLS (sym->etype) == S_DATA)
697 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
702 if (SPEC_SCLS (sym->etype) == S_EEPROM)
704 SPEC_OCLS (sym->etype) = eeprom;
709 /* again note that we have put it into the overlay segment
710 will remove and put into the 'data' segment if required after
711 overlay analysis has been done */
712 if (options.model == MODEL_SMALL) {
713 SPEC_OCLS (sym->etype) =
714 (options.noOverlay ? port->mem.default_local_map
717 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
722 /*-----------------------------------------------------------------*/
723 /* deallocLocal - deallocates the local variables */
724 /*-----------------------------------------------------------------*/
726 deallocLocal (symbol * csym)
730 for (sym = csym; sym; sym = sym->next)
735 /* if it is on the stack */
738 if (options.useXstack)
739 xstackPtr -= getSize (sym->type);
741 stackPtr -= getSize (sym->type);
743 /* if not used give a warning */
744 if (!sym->isref && !IS_STATIC (sym->etype))
745 werror (W_NO_REFERENCE,
746 currFunc ? currFunc->name : "(unknown)",
747 "local variable", sym->name);
748 /* now delete it from the symbol table */
749 deleteSym (SymbolTab, sym, sym->name);
753 /*-----------------------------------------------------------------*/
754 /* overlay2data - moves declarations from the overlay seg to data */
755 /*-----------------------------------------------------------------*/
761 for (sym = setFirstItem (overlay->syms); sym;
762 sym = setNextItem (overlay->syms))
765 SPEC_OCLS (sym->etype) = data;
769 setToNull ((void *) &overlay->syms);
773 /*-----------------------------------------------------------------*/
774 /* overlay2Set - will add all symbols from the overlay segment to */
775 /* the set of sets containing the overlable symbols */
776 /*-----------------------------------------------------------------*/
783 for (sym = setFirstItem (overlay->syms); sym;
784 sym = setNextItem (overlay->syms))
790 setToNull ((void *) &overlay->syms);
791 addSet (&ovrSetSets, oset);
795 /*-----------------------------------------------------------------*/
796 /* allocVariables - creates decl & assign storage class for a v */
797 /*-----------------------------------------------------------------*/
799 allocVariables (symbol * symChain)
806 /* go thru the symbol chain */
807 for (sym = symChain; sym; sym = sym->next)
810 /* if this is a typedef then add it */
811 /* to the typedef table */
812 if (IS_TYPEDEF (sym->etype))
814 /* check if the typedef already exists */
815 csym = findSym (TypedefTab, NULL, sym->name);
816 if (csym && csym->level == sym->level)
817 werror (E_DUPLICATE_TYPEDEF, sym->name);
819 SPEC_EXTR (sym->etype) = 0;
820 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
821 continue; /* go to the next one */
823 /* make sure it already exist */
824 csym = findSymWithLevel (SymbolTab, sym);
825 if (!csym || (csym && csym->level != sym->level))
828 /* check the declaration */
831 /* if this is a function or a pointer to function */
832 /* then args processing */
833 if (funcInChain (csym->type))
835 processFuncArgs (csym);
837 /* if register bank specified then update maxRegBank */
838 if (maxRegBank < FUNC_REGBANK (csym->type))
839 maxRegBank = FUNC_REGBANK (csym->type);
840 /*JCF: Mark the register bank as used*/
841 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
844 /* if this is a extern variable then change the */
845 /* level to zero temporarily */
846 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
848 saveLevel = csym->level;
852 /* if this is a literal then it is an enumerated */
853 /* type so need not allocate it space for it */
854 if (IS_LITERAL (sym->etype))
857 /* generate the actual declaration */
862 stack += getSize (csym->type);
867 /* restore the level */
868 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
869 csym->level = saveLevel;
875 /*-----------------------------------------------------------------*/
876 /* redoStackOffsets :- will reassign the values for stack offsets */
877 /*-----------------------------------------------------------------*/
879 redoStackOffsets (void)
885 /* after register allocation is complete we know
886 which variables will need to be assigned space
887 on the stack. We will eliminate those variables
888 which do not have the allocReq flag thus reducing
890 for (sym = setFirstItem (istack->syms); sym;
891 sym = setNextItem (istack->syms))
894 int size = getSize (sym->type);
895 /* nothing to do with parameters so continue */
896 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
899 if (IS_AGGREGATE (sym->type))
901 if (port->stack.direction > 0)
903 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
909 SPEC_STAK (sym->etype) = sym->stack = sPtr;
914 /* if allocation not required then subtract
915 size from overall stack size & continue */
918 currFunc->stack -= size;
919 SPEC_STAK (currFunc->etype) -= size;
923 if (port->stack.direction > 0)
925 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
931 SPEC_STAK (sym->etype) = sym->stack = sPtr;
935 /* do the same for the external stack */
937 for (sym = setFirstItem (xstack->syms); sym;
938 sym = setNextItem (xstack->syms))
941 int size = getSize (sym->type);
942 /* nothing to do with parameters so continue */
943 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
946 if (IS_AGGREGATE (sym->type))
948 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
953 /* if allocation not required then subtract
954 size from overall stack size & continue */
957 currFunc->xstack -= size;
958 SPEC_STAK (currFunc->etype) -= size;
962 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
968 /*-----------------------------------------------------------------*/
969 /* printAllocInfoSeg- print the allocation for a given section */
970 /*-----------------------------------------------------------------*/
972 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
981 for (sym = setFirstItem (map->syms); sym;
982 sym = setNextItem (map->syms))
987 if (sym->localof != func)
990 fprintf (of, ";%-25s Allocated ", sym->name);
992 /* if assigned to registers */
993 if (!sym->allocreq && sym->reqv)
997 sym = OP_SYMBOL (sym->reqv);
998 if (!sym->isspilt || sym->remat)
1000 fprintf (of, "to registers ");
1001 for (i = 0; i < 4 && sym->regs[i]; i++)
1002 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1008 sym = sym->usl.spillLoc;
1015 fprintf (of, "to stack - offset %d\n", sym->stack);
1019 /* otherwise give rname */
1020 fprintf (of, "with name '%s'\n", sym->rname);
1024 /*-----------------------------------------------------------------*/
1025 /* canOverlayLocals - returns true if the local variables can overlayed */
1026 /*-----------------------------------------------------------------*/
1028 canOverlayLocals (eBBlock ** ebbs, int count)
1031 /* if staticAuto is in effect or the current function
1032 being compiled is reentrant or the overlay segment
1033 is empty or no overlay option is in effect then */
1034 if (options.noOverlay ||
1035 options.stackAuto ||
1037 (IFFUNC_ISREENT (currFunc->type) ||
1038 FUNC_ISISR (currFunc->type))) ||
1039 elementsInSet (overlay->syms) == 0)
1043 /* if this is a forces overlay */
1044 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1046 /* otherwise do thru the blocks and see if there
1047 any function calls if found then return false */
1048 for (i = 0; i < count; i++)
1052 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1054 if (ic->op == CALL) {
1055 sym_link *ftype = operandType(IC_LEFT(ic));
1056 /* builtins only can use overlays */
1057 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1058 } else if (ic->op == PCALL) return FALSE;
1062 /* no function calls found return TRUE */
1066 /*-----------------------------------------------------------------*/
1067 /* doOverlays - move the overlay segment to appropriate location */
1068 /*-----------------------------------------------------------------*/
1070 doOverlays (eBBlock ** ebbs, int count)
1076 /* check if the parameters and local variables
1077 of this function can be put in the overlay segment
1078 This check is essentially to see if the function
1079 calls any other functions if yes then we cannot
1081 if (canOverlayLocals (ebbs, count))
1082 /* if we can then put the parameters &
1083 local variables in the overlay set */
1086 /* otherwise put them into data where
1091 /*-----------------------------------------------------------------*/
1092 /* printAllocInfo - prints allocation information for a function */
1093 /*-----------------------------------------------------------------*/
1095 printAllocInfo (symbol * func, FILE * of)
1103 /* must be called after register allocation is complete */
1104 fprintf (of, ";------------------------------------------------------------\n");
1105 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1106 fprintf (of, ";------------------------------------------------------------\n");
1108 printAllocInfoSeg (xstack, func, of);
1109 printAllocInfoSeg (istack, func, of);
1110 printAllocInfoSeg (code, func, of);
1111 printAllocInfoSeg (data, func, of);
1112 printAllocInfoSeg (xdata, func, of);
1113 printAllocInfoSeg (idata, func, of);
1114 printAllocInfoSeg (sfr, func, of);
1115 printAllocInfoSeg (sfrbit, func, of);
1119 set *tempOverlaySyms = overlay->syms;
1121 /* search the set of overlay sets for local variables/parameters */
1122 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1123 ovrset = setNextItem (ovrSetSets))
1125 overlay->syms = ovrset;
1126 printAllocInfoSeg (overlay, func, of);
1128 overlay->syms = tempOverlaySyms;
1131 fprintf (of, ";------------------------------------------------------------\n");