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)
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 /* if both absolute address & initial */
355 /* value specified then error */
356 if (IS_ABSOLUTE (sym->etype) && sym->ival)
358 werror (E_SFR_INIT, sym->name);
362 SPEC_OCLS (sym->etype) =
363 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
369 /* if this is a bit variable and no storage class */
370 if (SPEC_NOUN (sym->etype) == V_BIT
371 && SPEC_SCLS (sym->etype) == S_BIT)
373 SPEC_OCLS (sym->etype) = bit;
378 /* if bit storage class */
379 if (SPEC_SCLS (sym->etype) == S_SBIT)
381 SPEC_OCLS (sym->etype) = bit;
386 /* register storage class ignored changed to FIXED */
387 if (SPEC_SCLS (sym->etype) == S_REGISTER)
388 SPEC_SCLS (sym->etype) = S_FIXED;
390 /* if data specified then */
391 if (SPEC_SCLS (sym->etype) == S_DATA)
393 /* set the output class */
394 SPEC_OCLS (sym->etype) = data;
395 /* generate the symbol */
400 /* if it is fixed, then allocate depending on the */
401 /* current memory model, same for automatics */
402 if (SPEC_SCLS (sym->etype) == S_FIXED ||
403 SPEC_SCLS (sym->etype) == S_AUTO) {
404 if (port->mem.default_globl_map != xdata) {
405 /* set the output class */
406 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
407 /* generate the symbol */
411 SPEC_SCLS (sym->etype) = S_XDATA;
415 /* if code change to constant */
416 if (SPEC_SCLS (sym->etype) == S_CODE) {
417 SPEC_OCLS (sym->etype) = statsg;
422 if (SPEC_SCLS (sym->etype) == S_XDATA)
424 // should we move this to the initialized data segment?
425 if (port->genXINIT &&
426 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
427 SPEC_OCLS(sym->etype)=xidata;
429 SPEC_OCLS (sym->etype) = xdata;
435 if (SPEC_SCLS (sym->etype) == S_IDATA)
437 SPEC_OCLS (sym->etype) = idata;
443 if (SPEC_SCLS (sym->etype) == S_EEPROM)
445 SPEC_OCLS (sym->etype) = eeprom;
453 /*-----------------------------------------------------------------*/
454 /* allocParms - parameters are always passed on stack */
455 /*-----------------------------------------------------------------*/
457 allocParms (value * val)
462 for (lval = val; lval; lval = lval->next, pNum++)
465 /* check the declaration */
466 checkDecl (lval->sym, 0);
468 /* if this a register parm then allocate
469 it as a local variable by adding it
470 to the first block we see in the body */
471 if (IS_REGPARM (lval->etype))
474 /* mark it as my parameter */
475 lval->sym->ismyparm = 1;
476 lval->sym->localof = currFunc;
479 /* if automatic variables r 2b stacked */
480 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
484 lval->sym->onStack = 1;
486 /* choose which stack 2 use */
487 /* use xternal stack */
488 if (options.useXstack)
490 /* PENDING: stack direction support */
491 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
492 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
493 xstackPtr - getSize (lval->type);
494 xstackPtr -= getSize (lval->type);
497 { /* use internal stack */
498 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
499 if (port->stack.direction > 0)
501 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
502 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
503 getSize (lval->type) -
504 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
505 stackPtr -= getSize (lval->type);
509 /* This looks like the wrong order but it turns out OK... */
510 /* PENDING: isr, bank overhead, ... */
511 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
513 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
514 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
516 stackPtr += getSize (lval->type);
519 allocIntoSeg (lval->sym);
522 { /* allocate them in the automatic space */
523 /* generate a unique name */
524 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
525 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
526 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
528 /* if declared in external storage */
529 if (SPEC_SCLS (lval->etype) == S_XDATA)
530 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
532 /* other wise depending on the memory model
533 note here that we put it into the overlay segment
534 first, we will remove it from the overlay segment
535 after the overlay determination has been done */
536 if (options.model == MODEL_SMALL)
538 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
539 (options.noOverlay ? port->mem.default_local_map
544 SPEC_SCLS (lval->etype) = S_XDATA;
545 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
547 allocIntoSeg (lval->sym);
554 /*-----------------------------------------------------------------*/
555 /* deallocParms - parameters are always passed on stack */
556 /*-----------------------------------------------------------------*/
558 deallocParms (value * val)
562 for (lval = val; lval; lval = lval->next)
565 /* unmark is myparm */
566 lval->sym->ismyparm = 0;
568 /* delete it from the symbol table */
569 deleteSym (SymbolTab, lval->sym, lval->sym->name);
571 if (!lval->sym->isref)
573 lval->sym->allocreq = 0;
574 werror (W_NO_REFERENCE, currFunc->name,
575 "function argument", lval->sym->name);
578 /* move the rname if any to the name for both val & sym */
579 /* and leave a copy of it in the symbol table */
580 if (lval->sym->rname[0])
582 char buffer[SDCC_NAME_MAX];
583 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
584 lval->sym = copySymbol (lval->sym);
585 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
586 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
587 strncpyz (lval->name, buffer, sizeof(lval->name));
588 addSym (SymbolTab, lval->sym, lval->sym->name,
589 lval->sym->level, lval->sym->block, 1);
590 lval->sym->_isparm = 1;
591 if (!isinSet (operKeyReset, lval->sym)) {
592 addSet(&operKeyReset, lval->sym);
601 /*-----------------------------------------------------------------*/
602 /* allocLocal - allocate local variables */
603 /*-----------------------------------------------------------------*/
605 allocLocal (symbol * sym)
608 /* generate an unique name */
609 SNPRINTF (sym->rname, sizeof(sym->rname),
612 currFunc->name, sym->name, sym->level, sym->block);
615 sym->localof = currFunc;
617 /* if this is a static variable */
618 if (IS_STATIC (sym->etype))
625 /* if volatile then */
626 if (IS_VOLATILE (sym->etype))
629 /* this is automatic */
631 /* if it to be placed on the stack */
632 if (options.stackAuto || reentrant) {
634 if (options.useXstack) {
635 /* PENDING: stack direction for xstack */
636 SPEC_OCLS (sym->etype) = xstack;
637 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
638 xstackPtr += getSize (sym->type);
640 SPEC_OCLS (sym->etype) = istack;
641 if (port->stack.direction > 0) {
642 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
643 stackPtr += getSize (sym->type);
645 stackPtr -= getSize (sym->type);
646 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
653 /* else depending on the storage class specified */
654 if (SPEC_SCLS (sym->etype) == S_XDATA)
656 SPEC_OCLS (sym->etype) = xdata;
661 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
662 SPEC_OCLS (sym->etype) = statsg;
667 if (SPEC_SCLS (sym->etype) == S_IDATA)
669 SPEC_OCLS (sym->etype) = idata;
675 /* if this is a function then assign code space */
676 if (IS_FUNC (sym->type))
678 SPEC_OCLS (sym->etype) = code;
682 /* if this is a SFR or SBIT */
683 if (SPEC_SCLS (sym->etype) == S_SFR ||
684 SPEC_SCLS (sym->etype) == S_SBIT)
687 /* if both absolute address & initial */
688 /* value specified then error */
689 if (IS_ABSOLUTE (sym->etype) && sym->ival)
691 werror (E_SFR_INIT, sym->name);
695 SPEC_OCLS (sym->etype) =
696 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
702 /* if this is a bit variable and no storage class */
703 if (SPEC_NOUN (sym->etype) == V_BIT
704 && (SPEC_SCLS (sym->etype) == S_BIT))
706 SPEC_OCLS (sym->etype) = bit;
711 if (SPEC_SCLS (sym->etype) == S_DATA)
713 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
718 if (SPEC_SCLS (sym->etype) == S_EEPROM)
720 SPEC_OCLS (sym->etype) = eeprom;
725 /* again note that we have put it into the overlay segment
726 will remove and put into the 'data' segment if required after
727 overlay analysis has been done */
728 if (options.model == MODEL_SMALL) {
729 SPEC_OCLS (sym->etype) =
730 (options.noOverlay ? port->mem.default_local_map
733 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
738 /*-----------------------------------------------------------------*/
739 /* deallocLocal - deallocates the local variables */
740 /*-----------------------------------------------------------------*/
742 deallocLocal (symbol * csym)
746 for (sym = csym; sym; sym = sym->next)
751 /* if it is on the stack */
754 if (options.useXstack)
755 xstackPtr -= getSize (sym->type);
757 stackPtr -= getSize (sym->type);
759 /* if not used give a warning */
760 if (!sym->isref && !IS_STATIC (sym->etype))
761 werror (W_NO_REFERENCE, currFunc->name,
762 "local variable", sym->name);
763 /* now delete it from the symbol table */
764 deleteSym (SymbolTab, sym, sym->name);
768 /*-----------------------------------------------------------------*/
769 /* overlay2data - moves declarations from the overlay seg to data */
770 /*-----------------------------------------------------------------*/
776 for (sym = setFirstItem (overlay->syms); sym;
777 sym = setNextItem (overlay->syms))
780 SPEC_OCLS (sym->etype) = data;
784 setToNull ((void **) &overlay->syms);
788 /*-----------------------------------------------------------------*/
789 /* overlay2Set - will add all symbols from the overlay segment to */
790 /* the set of sets containing the overlable symbols */
791 /*-----------------------------------------------------------------*/
798 for (sym = setFirstItem (overlay->syms); sym;
799 sym = setNextItem (overlay->syms))
805 setToNull ((void **) &overlay->syms);
806 addSet (&ovrSetSets, oset);
810 /*-----------------------------------------------------------------*/
811 /* allocVariables - creates decl & assign storage class for a v */
812 /*-----------------------------------------------------------------*/
814 allocVariables (symbol * symChain)
821 /* go thru the symbol chain */
822 for (sym = symChain; sym; sym = sym->next)
825 /* if this is a typedef then add it */
826 /* to the typedef table */
827 if (IS_TYPEDEF (sym->etype))
829 /* check if the typedef already exists */
830 csym = findSym (TypedefTab, NULL, sym->name);
831 if (csym && csym->level == sym->level)
832 werror (E_DUPLICATE_TYPEDEF, sym->name);
834 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
835 continue; /* go to the next one */
837 /* make sure it already exist */
838 csym = findSymWithLevel (SymbolTab, sym);
839 if (!csym || (csym && csym->level != sym->level))
842 /* check the declaration */
845 /* if this is a function or a pointer to function */
846 /* then args processing */
847 if (funcInChain (csym->type))
849 processFuncArgs (csym);
851 /* if register bank specified then update maxRegBank */
852 if (maxRegBank < FUNC_REGBANK (csym->type))
853 maxRegBank = FUNC_REGBANK (csym->type);
854 /*JCF: Mark the register bank as used*/
855 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
858 /* if this is a extern variable then change the */
859 /* level to zero temporarily */
860 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
862 saveLevel = csym->level;
866 /* if this is a literal then it is an enumerated */
867 /* type so need not allocate it space for it */
868 if (IS_LITERAL (sym->etype))
871 /* generate the actual declaration */
876 stack += getSize (csym->type);
881 /* restore the level */
882 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
883 csym->level = saveLevel;
889 /*-----------------------------------------------------------------*/
890 /* redoStackOffsets :- will reassign the values for stack offsets */
891 /*-----------------------------------------------------------------*/
893 redoStackOffsets (void)
899 /* after register allocation is complete we know
900 which variables will need to be assigned space
901 on the stack. We will eliminate those variables
902 which do not have the allocReq flag thus reducing
904 for (sym = setFirstItem (istack->syms); sym;
905 sym = setNextItem (istack->syms))
908 int size = getSize (sym->type);
909 /* nothing to do with parameters so continue */
910 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
913 if (IS_AGGREGATE (sym->type))
915 if (port->stack.direction > 0)
917 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
923 SPEC_STAK (sym->etype) = sym->stack = sPtr;
928 /* if allocation not required then subtract
929 size from overall stack size & continue */
932 currFunc->stack -= size;
933 SPEC_STAK (currFunc->etype) -= size;
937 if (port->stack.direction > 0)
939 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
945 SPEC_STAK (sym->etype) = sym->stack = sPtr;
949 /* do the same for the external stack */
951 for (sym = setFirstItem (xstack->syms); sym;
952 sym = setNextItem (xstack->syms))
955 int size = getSize (sym->type);
956 /* nothing to do with parameters so continue */
957 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
960 if (IS_AGGREGATE (sym->type))
962 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
967 /* if allocation not required then subtract
968 size from overall stack size & continue */
971 currFunc->xstack -= size;
972 SPEC_STAK (currFunc->etype) -= size;
976 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
980 /* if the debug option is set then output the
981 symbols to the map file */
984 for (sym = setFirstItem (istack->syms); sym;
985 sym = setNextItem (istack->syms))
986 cdbSymbol (sym, cdbFile, FALSE, FALSE);
988 for (sym = setFirstItem (xstack->syms); sym;
989 sym = setNextItem (xstack->syms))
990 cdbSymbol (sym, cdbFile, FALSE, FALSE);
994 /*-----------------------------------------------------------------*/
995 /* printAllocInfoSeg- print the allocation for a given section */
996 /*-----------------------------------------------------------------*/
998 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
1007 for (sym = setFirstItem (map->syms); sym;
1008 sym = setNextItem (map->syms))
1011 if (sym->level == 0)
1013 if (sym->localof != func)
1015 fprintf (of, ";%-25s Allocated to ", sym->name);
1017 /* if assigned to registers */
1018 if (!sym->allocreq && sym->reqv)
1022 sym = OP_SYMBOL (sym->reqv);
1023 fprintf (of, "registers ");
1024 for (i = 0; i < 4 && sym->regs[i]; i++)
1025 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1033 fprintf (of, "stack - offset %d\n", sym->stack);
1037 /* otherwise give rname */
1038 fprintf (of, "in memory with name '%s'\n", sym->rname);
1042 /*-----------------------------------------------------------------*/
1043 /* canOverlayLocals - returns true if the local variables can overlayed */
1044 /*-----------------------------------------------------------------*/
1046 canOverlayLocals (eBBlock ** ebbs, int count)
1049 /* if staticAuto is in effect or the current function
1050 being compiled is reentrant or the overlay segment
1051 is empty or no overlay option is in effect then */
1052 if (options.noOverlay ||
1053 options.stackAuto ||
1055 (IFFUNC_ISREENT (currFunc->type) ||
1056 FUNC_ISISR (currFunc->type))) ||
1057 elementsInSet (overlay->syms) == 0)
1061 /* if this is a forces overlay */
1062 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1064 /* otherwise do thru the blocks and see if there
1065 any function calls if found then return false */
1066 for (i = 0; i < count; i++)
1070 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1072 if (ic->op == CALL) {
1073 sym_link *ftype = operandType(IC_LEFT(ic));
1074 /* builtins only can use overlays */
1075 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1076 } else if (ic->op == PCALL) return FALSE;
1080 /* no function calls found return TRUE */
1084 /*-----------------------------------------------------------------*/
1085 /* doOverlays - move the overlay segment to appropriate location */
1086 /*-----------------------------------------------------------------*/
1088 doOverlays (eBBlock ** ebbs, int count)
1094 /* check if the parameters and local variables
1095 of this function can be put in the overlay segment
1096 This check is essentially to see if the function
1097 calls any other functions if yes then we cannot
1099 if (canOverlayLocals (ebbs, count))
1100 /* if we can then put the parameters &
1101 local variables in the overlay set */
1104 /* otherwise put them into data where
1109 /*-----------------------------------------------------------------*/
1110 /* printAllocInfo - prints allocation information for a function */
1111 /*-----------------------------------------------------------------*/
1113 printAllocInfo (symbol * func, FILE * of)
1118 /* must be called after register allocation is complete */
1119 fprintf (of, ";------------------------------------------------------------\n");
1120 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1121 fprintf (of, ";------------------------------------------------------------\n");
1123 printAllocInfoSeg (xstack, func, of);
1124 printAllocInfoSeg (istack, func, of);
1125 printAllocInfoSeg (code, func, of);
1126 printAllocInfoSeg (data, func, of);
1127 printAllocInfoSeg (xdata, func, of);
1128 printAllocInfoSeg (idata, func, of);
1129 printAllocInfoSeg (sfr, func, of);
1130 printAllocInfoSeg (sfrbit, func, of);
1131 fprintf (of, ";------------------------------------------------------------\n");