1 //#define LIVERANGEHUNT
7 /*-----------------------------------------------------------------*/
8 /* SDCCmem.c - 8051 memory management routines */
9 /*-----------------------------------------------------------------*/
14 memmap *xstack = NULL; /* xternal stack data */
15 memmap *istack = NULL; /* internal stack */
16 memmap *code = NULL; /* code segment */
17 memmap *data = NULL; /* internal data upto 128 */
18 memmap *xdata = NULL; /* external data */
19 memmap *xidata = NULL; /* the initialized xdata */
20 memmap *xinit = NULL; /* the initializers for xidata */
21 memmap *idata = NULL; /* internal data upto 256 */
22 memmap *bit = NULL; /* bit addressable space */
23 memmap *statsg = NULL; /* the constant data segment */
24 memmap *sfr = NULL; /* register space */
25 memmap *reg = NULL; /* register space */
26 memmap *sfrbit = NULL; /* sfr bit space */
27 memmap *generic = NULL; /* is a generic pointer */
28 memmap *overlay = NULL; /* overlay segment */
29 memmap *eeprom = NULL; /* eeprom location */
30 memmap *home = NULL; /* Unswitchable code bank */
32 /* this is a set of sets each set containing
33 symbols in a single overlay */
34 set *ovrSetSets = NULL;
37 int fatalError = 0; /* fatal error flag */
39 /*-----------------------------------------------------------------*/
40 /* allocMap - allocates a memory map */
41 /*-----------------------------------------------------------------*/
43 allocMap (char rspace, /* sfr space */
44 char farmap, /* far or near segment */
45 char paged, /* can this segment be paged */
46 char direct, /* directly addressable */
47 char bitaddr, /* bit addressable space */
48 char codemap, /* this is code space */
49 unsigned sloc, /* starting location */
50 const char *name, /* 2 character name */
51 char dbName, /* debug name */
52 int ptrType /* pointer type for this space */
57 if (!(map = Safe_alloc (sizeof (memmap))))
59 werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap));
63 memset (map, ZERO, sizeof (memmap));
69 map->codesp = codemap;
73 map->ptrType = ptrType;
74 if (!(map->oFile = tempfile ()))
76 werror (E_TMPFILE_FAILED);
79 addSetHead (&tmpfileSet, map->oFile);
84 /*-----------------------------------------------------------------*/
85 /* initMem - allocates and initializes all the segments */
86 /*-----------------------------------------------------------------*/
90 /* allocate all the segments */
91 /* xternal stack segment ;
99 POINTER-TYPE - FPOINTER
101 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
103 /* internal stack segment ;
111 POINTER-TYPE - POINTER
114 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc,
115 ISTACK_NAME, 'B', POINTER);
128 POINTER-TYPE - CPOINTER
130 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
140 POINTER-TYPE - CPOINTER
142 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
144 /* Static segment (code for variables );
152 POINTER-TYPE - CPOINTER
154 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
156 /* Data segment - internal storage segment ;
164 POINTER-TYPE - POINTER
166 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
168 /* overlay segment - same as internal storage segment ;
176 POINTER-TYPE - POINTER
179 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
184 /* Xternal Data segment -
192 POINTER-TYPE - FPOINTER
194 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
195 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
196 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
198 /* Inderectly addressed internal data segment
206 POINTER-TYPE - IPOINTER
209 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,
210 IDATA_NAME, 'G', IPOINTER);
215 /* Static segment (code for variables );
223 POINTER-TYPE - _NONE_
225 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
227 /* Special function register space :-
235 POINTER-TYPE - _NONE_
237 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
247 POINTER-TYPE - _NONE_
249 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
259 POINTER-TYPE - _NONE_
261 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
271 POINTER-TYPE - EEPPOINTER
273 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
275 /* the unknown map */
276 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
280 /*-----------------------------------------------------------------*/
281 /* allocIntoSeg - puts a symbol into a memory segment */
282 /*-----------------------------------------------------------------*/
284 allocIntoSeg (symbol * sym)
286 memmap *segment = SPEC_OCLS (sym->etype);
287 addSet (&segment->syms, sym);
290 /*-----------------------------------------------------------------*/
291 /* deleteFromSeg - deletes a symbol from segment used when a var */
292 /* firest declared as "extern" then no extern */
293 /*-----------------------------------------------------------------*/
294 void deleteFromSeg(symbol *sym)
296 if (SPEC_OCLS(sym->etype)) {
297 memmap *segment = SPEC_OCLS (sym->etype);
298 deleteSetItem(&segment->syms,sym);
303 /*-----------------------------------------------------------------*/
304 /* allocGlobal - assigns the output segment to a global var */
305 /*-----------------------------------------------------------------*/
307 allocGlobal (symbol * sym)
310 /* symbol name is internal name */
311 if (!sym->level) /* local statics can come here */
312 SNPRINTF (sym->rname, sizeof(sym->rname),
313 "%s%s", port->fun_prefix, sym->name);
315 /* add it to the operandKey reset */
316 if (!isinSet (operKeyReset, sym)) {
317 addSet(&operKeyReset, sym);
320 /* if this is a literal e.g. enumerated type */
321 /* put it in the data segment & do nothing */
322 if (IS_LITERAL (sym->etype))
324 SPEC_OCLS (sym->etype) = data;
328 /* if this is a function then assign code space */
329 if (IS_FUNC (sym->type))
331 SPEC_OCLS (sym->etype) = code;
332 /* if this is an interrupt service routine
333 then put it in the interrupt service array */
334 if (FUNC_ISISR (sym->type) && !options.noiv)
337 if (interrupts[FUNC_INTNO (sym->type)])
338 werror (E_INT_DEFINED,
339 FUNC_INTNO (sym->type),
340 interrupts[FUNC_INTNO (sym->type)]->name);
342 interrupts[FUNC_INTNO (sym->type)] = sym;
344 /* automagically extend the maximum interrupts */
345 if (FUNC_INTNO (sym->type) >= maxInterrupts)
346 maxInterrupts = FUNC_INTNO (sym->type) + 1;
348 /* if it is not compiler defined */
355 /* if this is a SFR or SBIT */
356 if (SPEC_SCLS (sym->etype) == S_SFR ||
357 SPEC_SCLS (sym->etype) == S_SBIT)
360 /* if both absolute address & initial */
361 /* value specified then error */
362 if (IS_ABSOLUTE (sym->etype) && sym->ival)
364 werror (E_SFR_INIT, sym->name);
368 SPEC_OCLS (sym->etype) =
369 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
375 /* if this is a bit variable and no storage class */
376 if (SPEC_NOUN (sym->etype) == V_BIT
377 && SPEC_SCLS (sym->etype) == S_BIT)
379 SPEC_OCLS (sym->etype) = bit;
384 /* if bit storage class */
385 if (SPEC_SCLS (sym->etype) == S_SBIT)
387 SPEC_OCLS (sym->etype) = bit;
392 /* register storage class ignored changed to FIXED */
393 if (SPEC_SCLS (sym->etype) == S_REGISTER)
394 SPEC_SCLS (sym->etype) = S_FIXED;
396 /* if data specified then */
397 if (SPEC_SCLS (sym->etype) == S_DATA)
399 /* set the output class */
400 SPEC_OCLS (sym->etype) = data;
401 /* generate the symbol */
406 /* if it is fixed, then allocate depending on the */
407 /* current memory model, same for automatics */
408 if (SPEC_SCLS (sym->etype) == S_FIXED ||
409 SPEC_SCLS (sym->etype) == S_AUTO) {
410 if (port->mem.default_globl_map != xdata) {
411 /* set the output class */
412 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
413 /* generate the symbol */
417 SPEC_SCLS (sym->etype) = S_XDATA;
421 /* if code change to constant */
422 if (SPEC_SCLS (sym->etype) == S_CODE) {
423 SPEC_OCLS (sym->etype) = statsg;
428 if (SPEC_SCLS (sym->etype) == S_XDATA)
430 // should we move this to the initialized data segment?
431 if (port->genXINIT &&
432 sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
433 SPEC_OCLS(sym->etype)=xidata;
435 SPEC_OCLS (sym->etype) = xdata;
441 if (SPEC_SCLS (sym->etype) == S_IDATA)
443 SPEC_OCLS (sym->etype) = idata;
449 if (SPEC_SCLS (sym->etype) == S_EEPROM)
451 SPEC_OCLS (sym->etype) = eeprom;
459 /*-----------------------------------------------------------------*/
460 /* allocParms - parameters are always passed on stack */
461 /*-----------------------------------------------------------------*/
463 allocParms (value * val)
468 for (lval = val; lval; lval = lval->next, pNum++)
471 /* check the declaration */
472 checkDecl (lval->sym, 0);
474 /* if this a register parm then allocate
475 it as a local variable by adding it
476 to the first block we see in the body */
477 if (IS_REGPARM (lval->etype))
480 /* mark it as my parameter */
481 lval->sym->ismyparm = 1;
482 lval->sym->localof = currFunc;
485 /* if automatic variables r 2b stacked */
486 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
490 lval->sym->onStack = 1;
492 /* choose which stack 2 use */
493 /* use xternal stack */
494 if (options.useXstack)
496 /* PENDING: stack direction support */
497 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
498 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
499 xstackPtr - getSize (lval->type);
500 xstackPtr -= getSize (lval->type);
503 { /* use internal stack */
504 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
505 if (port->stack.direction > 0)
507 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
508 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
509 getSize (lval->type) -
510 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
511 stackPtr -= getSize (lval->type);
515 /* This looks like the wrong order but it turns out OK... */
516 /* PENDING: isr, bank overhead, ... */
517 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
519 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
520 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
522 stackPtr += getSize (lval->type);
525 allocIntoSeg (lval->sym);
528 { /* allocate them in the automatic space */
529 /* generate a unique name */
530 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
531 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
532 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
534 /* if declared in external storage */
535 if (SPEC_SCLS (lval->etype) == S_XDATA)
536 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
538 /* other wise depending on the memory model
539 note here that we put it into the overlay segment
540 first, we will remove it from the overlay segment
541 after the overlay determination has been done */
542 if (options.model == MODEL_SMALL)
544 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
545 (options.noOverlay ? port->mem.default_local_map
550 SPEC_SCLS (lval->etype) = S_XDATA;
551 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
553 allocIntoSeg (lval->sym);
560 /*-----------------------------------------------------------------*/
561 /* deallocParms - parameters are always passed on stack */
562 /*-----------------------------------------------------------------*/
564 deallocParms (value * val)
568 for (lval = val; lval; lval = lval->next)
571 /* unmark is myparm */
572 lval->sym->ismyparm = 0;
574 /* delete it from the symbol table */
575 deleteSym (SymbolTab, lval->sym, lval->sym->name);
577 if (!lval->sym->isref)
579 lval->sym->allocreq = 0;
580 werror (W_NO_REFERENCE, currFunc->name,
581 "function argument", lval->sym->name);
584 /* move the rname if any to the name for both val & sym */
585 /* and leave a copy of it in the symbol table */
586 if (lval->sym->rname[0])
588 char buffer[SDCC_NAME_MAX];
589 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
590 lval->sym = copySymbol (lval->sym);
591 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
592 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
593 strncpyz (lval->name, buffer, sizeof(lval->name));
594 addSym (SymbolTab, lval->sym, lval->sym->name,
595 lval->sym->level, lval->sym->block, 1);
596 lval->sym->_isparm = 1;
597 if (!isinSet (operKeyReset, lval->sym)) {
598 addSet(&operKeyReset, lval->sym);
607 /*-----------------------------------------------------------------*/
608 /* allocLocal - allocate local variables */
609 /*-----------------------------------------------------------------*/
611 allocLocal (symbol * sym)
614 /* generate an unique name */
615 SNPRINTF (sym->rname, sizeof(sym->rname),
618 currFunc->name, sym->name, sym->level, sym->block);
621 sym->localof = currFunc;
623 /* if this is a static variable */
624 if (IS_STATIC (sym->etype))
631 /* if volatile then */
632 if (IS_VOLATILE (sym->etype))
635 /* this is automatic */
637 /* if it to be placed on the stack */
638 if (options.stackAuto || reentrant) {
640 if (options.useXstack) {
641 /* PENDING: stack direction for xstack */
642 SPEC_OCLS (sym->etype) = xstack;
643 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
644 xstackPtr += getSize (sym->type);
646 SPEC_OCLS (sym->etype) = istack;
647 if (port->stack.direction > 0) {
648 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
649 stackPtr += getSize (sym->type);
651 stackPtr -= getSize (sym->type);
652 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
659 /* else depending on the storage class specified */
660 if (SPEC_SCLS (sym->etype) == S_XDATA)
662 SPEC_OCLS (sym->etype) = xdata;
667 if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
668 SPEC_OCLS (sym->etype) = statsg;
673 if (SPEC_SCLS (sym->etype) == S_IDATA)
675 SPEC_OCLS (sym->etype) = idata;
681 /* if this is a function then assign code space */
682 if (IS_FUNC (sym->type))
684 SPEC_OCLS (sym->etype) = code;
688 /* if this is a SFR or SBIT */
689 if (SPEC_SCLS (sym->etype) == S_SFR ||
690 SPEC_SCLS (sym->etype) == S_SBIT)
693 /* if both absolute address & initial */
694 /* value specified then error */
695 if (IS_ABSOLUTE (sym->etype) && sym->ival)
697 werror (E_SFR_INIT, sym->name);
701 SPEC_OCLS (sym->etype) =
702 (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
708 /* if this is a bit variable and no storage class */
709 if (SPEC_NOUN (sym->etype) == V_BIT
710 && (SPEC_SCLS (sym->etype) == S_BIT))
712 SPEC_OCLS (sym->etype) = bit;
717 if (SPEC_SCLS (sym->etype) == S_DATA)
719 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
724 if (SPEC_SCLS (sym->etype) == S_EEPROM)
726 SPEC_OCLS (sym->etype) = eeprom;
731 /* again note that we have put it into the overlay segment
732 will remove and put into the 'data' segment if required after
733 overlay analysis has been done */
734 if (options.model == MODEL_SMALL) {
735 SPEC_OCLS (sym->etype) =
736 (options.noOverlay ? port->mem.default_local_map
739 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
744 /*-----------------------------------------------------------------*/
745 /* deallocLocal - deallocates the local variables */
746 /*-----------------------------------------------------------------*/
748 deallocLocal (symbol * csym)
752 for (sym = csym; sym; sym = sym->next)
757 /* if it is on the stack */
760 if (options.useXstack)
761 xstackPtr -= getSize (sym->type);
763 stackPtr -= getSize (sym->type);
765 /* if not used give a warning */
766 if (!sym->isref && !IS_STATIC (sym->etype))
767 werror (W_NO_REFERENCE, currFunc->name,
768 "local variable", sym->name);
769 /* now delete it from the symbol table */
770 deleteSym (SymbolTab, sym, sym->name);
774 /*-----------------------------------------------------------------*/
775 /* overlay2data - moves declarations from the overlay seg to data */
776 /*-----------------------------------------------------------------*/
782 for (sym = setFirstItem (overlay->syms); sym;
783 sym = setNextItem (overlay->syms))
786 SPEC_OCLS (sym->etype) = data;
790 setToNull ((void **) &overlay->syms);
794 /*-----------------------------------------------------------------*/
795 /* overlay2Set - will add all symbols from the overlay segment to */
796 /* the set of sets containing the overlable symbols */
797 /*-----------------------------------------------------------------*/
804 for (sym = setFirstItem (overlay->syms); sym;
805 sym = setNextItem (overlay->syms))
811 setToNull ((void **) &overlay->syms);
812 addSet (&ovrSetSets, oset);
816 /*-----------------------------------------------------------------*/
817 /* allocVariables - creates decl & assign storage class for a v */
818 /*-----------------------------------------------------------------*/
820 allocVariables (symbol * symChain)
827 /* go thru the symbol chain */
828 for (sym = symChain; sym; sym = sym->next)
831 /* if this is a typedef then add it */
832 /* to the typedef table */
833 if (IS_TYPEDEF (sym->etype))
835 /* check if the typedef already exists */
836 csym = findSym (TypedefTab, NULL, sym->name);
837 if (csym && csym->level == sym->level)
838 werror (E_DUPLICATE_TYPEDEF, sym->name);
840 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
841 continue; /* go to the next one */
843 /* make sure it already exist */
844 csym = findSymWithLevel (SymbolTab, sym);
845 if (!csym || (csym && csym->level != sym->level))
848 /* check the declaration */
851 /* if this is a function or a pointer to function */
852 /* then args processing */
853 if (funcInChain (csym->type))
855 #if 1 // jwk: TODO should have been done already in addDecl() (oclass????)
856 processFuncArgs (csym);
858 /* if register bank specified then update maxRegBank */
859 if (maxRegBank < FUNC_REGBANK (csym->type))
860 maxRegBank = FUNC_REGBANK (csym->type);
861 /*JCF: Mark the register bank as used*/
862 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
865 /* if this is a extern variable then change the */
866 /* level to zero temporarily */
867 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
869 saveLevel = csym->level;
873 /* if this is a literal then it is an enumerated */
874 /* type so need not allocate it space for it */
875 if (IS_LITERAL (sym->etype))
878 /* generate the actual declaration */
883 stack += getSize (csym->type);
888 /* restore the level */
889 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
890 csym->level = saveLevel;
896 /*-----------------------------------------------------------------*/
897 /* redoStackOffsets :- will reassign the values for stack offsets */
898 /*-----------------------------------------------------------------*/
900 redoStackOffsets (void)
906 /* after register allocation is complete we know
907 which variables will need to be assigned space
908 on the stack. We will eliminate those variables
909 which do not have the allocReq flag thus reducing
911 for (sym = setFirstItem (istack->syms); sym;
912 sym = setNextItem (istack->syms))
915 int size = getSize (sym->type);
916 /* nothing to do with parameters so continue */
917 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
920 if (IS_AGGREGATE (sym->type))
922 if (port->stack.direction > 0)
924 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
930 SPEC_STAK (sym->etype) = sym->stack = sPtr;
935 /* if allocation not required then subtract
936 size from overall stack size & continue */
939 currFunc->stack -= size;
940 SPEC_STAK (currFunc->etype) -= size;
944 if (port->stack.direction > 0)
946 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
952 SPEC_STAK (sym->etype) = sym->stack = sPtr;
956 /* do the same for the external stack */
958 for (sym = setFirstItem (xstack->syms); sym;
959 sym = setNextItem (xstack->syms))
962 int size = getSize (sym->type);
963 /* nothing to do with parameters so continue */
964 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
967 if (IS_AGGREGATE (sym->type))
969 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
974 /* if allocation not required then subtract
975 size from overall stack size & continue */
978 currFunc->xstack -= size;
979 SPEC_STAK (currFunc->etype) -= size;
983 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
987 /* if the debug option is set then output the
988 symbols to the map file */
991 for (sym = setFirstItem (istack->syms); sym;
992 sym = setNextItem (istack->syms))
993 cdbSymbol (sym, cdbFile, FALSE, FALSE);
995 for (sym = setFirstItem (xstack->syms); sym;
996 sym = setNextItem (xstack->syms))
997 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1001 /*-----------------------------------------------------------------*/
1002 /* printAllocInfoSeg- print the allocation for a given section */
1003 /*-----------------------------------------------------------------*/
1005 printAllocInfoSeg (memmap * map, symbol * func, FILE * of)
1014 for (sym = setFirstItem (map->syms); sym;
1015 sym = setNextItem (map->syms))
1018 if (sym->level == 0)
1020 if (sym->localof != func)
1022 fprintf (of, ";%-25s Allocated to ", sym->name);
1024 /* if assigned to registers */
1025 if (!sym->allocreq && sym->reqv)
1028 if (!OP_SYMBOL(sym->reqv)->nRegs) {
1029 LRH(printf ("*** warning: %s -> %s\n", sym->name, \
1030 OP_SYMBOL(sym->reqv)->name));
1032 sym = OP_SYMBOL (sym->reqv);
1033 fprintf (of, "registers ");
1034 for (i = 0; i < 4 && sym->regs[i]; i++)
1035 fprintf (of, "%s ", port->getRegName (sym->regs[i]));
1043 fprintf (of, "stack - offset %d\n", sym->stack);
1047 /* otherwise give rname */
1048 fprintf (of, "in memory with name '%s'\n", sym->rname);
1052 /*-----------------------------------------------------------------*/
1053 /* canOverlayLocals - returns true if the local variables can overlayed */
1054 /*-----------------------------------------------------------------*/
1056 canOverlayLocals (eBBlock ** ebbs, int count)
1059 /* if staticAuto is in effect or the current function
1060 being compiled is reentrant or the overlay segment
1061 is empty or no overlay option is in effect then */
1062 if (options.noOverlay ||
1063 options.stackAuto ||
1065 (IFFUNC_ISREENT (currFunc->type) ||
1066 FUNC_ISISR (currFunc->type))) ||
1067 elementsInSet (overlay->syms) == 0)
1071 /* if this is a forces overlay */
1072 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1074 /* otherwise do thru the blocks and see if there
1075 any function calls if found then return false */
1076 for (i = 0; i < count; i++)
1080 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1082 if (ic->op == CALL) {
1083 sym_link *ftype = operandType(IC_LEFT(ic));
1084 /* builtins only can use overlays */
1085 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1086 } else if (ic->op == PCALL) return FALSE;
1090 /* no function calls found return TRUE */
1094 /*-----------------------------------------------------------------*/
1095 /* doOverlays - move the overlay segment to appropriate location */
1096 /*-----------------------------------------------------------------*/
1098 doOverlays (eBBlock ** ebbs, int count)
1104 /* check if the parameters and local variables
1105 of this function can be put in the overlay segment
1106 This check is essentially to see if the function
1107 calls any other functions if yes then we cannot
1109 if (canOverlayLocals (ebbs, count))
1110 /* if we can then put the parameters &
1111 local variables in the overlay set */
1114 /* otherwise put them into data where
1119 /*-----------------------------------------------------------------*/
1120 /* printAllocInfo - prints allocation information for a function */
1121 /*-----------------------------------------------------------------*/
1123 printAllocInfo (symbol * func, FILE * of)
1128 /* must be called after register allocation is complete */
1129 fprintf (of, ";------------------------------------------------------------\n");
1130 fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name);
1131 fprintf (of, ";------------------------------------------------------------\n");
1133 printAllocInfoSeg (xstack, func, of);
1134 printAllocInfoSeg (istack, func, of);
1135 printAllocInfoSeg (code, func, of);
1136 printAllocInfoSeg (data, func, of);
1137 printAllocInfoSeg (xdata, func, of);
1138 printAllocInfoSeg (idata, func, of);
1139 printAllocInfoSeg (sfr, func, of);
1140 printAllocInfoSeg (sfrbit, func, of);
1141 fprintf (of, ";------------------------------------------------------------\n");