1 /*-----------------------------------------------------------------*/
2 /* SDCCmem.c - 8051 memory management routines */
3 /*-----------------------------------------------------------------*/
6 #include "dbuf_string.h"
9 memmap *xstack = NULL; /* xternal stack data */
10 memmap *istack = NULL; /* internal stack */
11 memmap *code = NULL; /* code segment */
12 memmap *data = NULL; /* internal data upto 128 */
13 memmap *pdata = NULL; /* paged external data */
14 memmap *xdata = NULL; /* external data */
15 memmap *xidata = NULL; /* the initialized xdata */
16 memmap *xinit = NULL; /* the initializers for xidata */
17 memmap *idata = NULL; /* internal data upto 256 */
18 memmap *bit = NULL; /* bit addressable space */
19 memmap *statsg = NULL; /* the constant data segment */
20 memmap *c_abs = NULL; /* constant absolute data */
21 memmap *x_abs = NULL; /* absolute xdata/pdata */
22 memmap *i_abs = NULL; /* absolute idata upto 256 */
23 memmap *d_abs = NULL; /* absolute data upto 128 */
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;
76 dbuf_init(&map->oBuf, 4096);
81 /*-----------------------------------------------------------------*/
82 /* initMem - allocates and initializes all the segments */
83 /*-----------------------------------------------------------------*/
87 /* allocate all the segments */
88 /* xternal stack segment ;
96 POINTER-TYPE - FPOINTER
98 xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER);
100 /* internal stack segment ;
108 POINTER-TYPE - POINTER
111 istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc,
112 ISTACK_NAME, 'B', POINTER);
125 POINTER-TYPE - CPOINTER
127 code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER);
137 POINTER-TYPE - CPOINTER
139 home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, HOME_NAME, 'C', CPOINTER);
141 /* Static segment (code for variables );
149 POINTER-TYPE - CPOINTER
151 statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER);
153 /* Constant Absolute Data segment (for variables );
161 POINTER-TYPE - CPOINTER
163 c_abs = allocMap (0, 1, 0, 0, 0, 1, 0, CABS_NAME, 'D', CPOINTER);
165 /* Data segment - internal storage segment ;
173 POINTER-TYPE - POINTER
175 data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
177 /* Absolute internal storage segment ;
185 POINTER-TYPE - POINTER
188 d_abs = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, IABS_NAME, 'E', POINTER);
193 /* overlay segment - same as internal storage segment ;
201 POINTER-TYPE - POINTER
204 overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER);
209 /* Xternal paged segment ;
217 POINTER-TYPE - PPOINTER
220 pdata = allocMap (0, 0, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER);
225 /* Xternal Data segment -
233 POINTER-TYPE - FPOINTER
235 xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER);
236 xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER);
237 xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER);
239 /* Indirectly addressed internal data segment
247 POINTER-TYPE - IPOINTER
250 idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,
251 IDATA_NAME, 'G', IPOINTER);
256 /* Indirectly addressed absolute internal segment
264 POINTER-TYPE - IPOINTER
267 i_abs = allocMap (0, 0, 0, 0, 0, 0, options.data_loc, IABS_NAME, 'E', IPOINTER);
280 POINTER-TYPE - _NONE_
282 bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0);
284 /* Special function register space :-
292 POINTER-TYPE - _NONE_
294 sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0);
304 POINTER-TYPE - _NONE_
306 reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0);
316 POINTER-TYPE - _NONE_
318 sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0);
328 POINTER-TYPE - EEPPOINTER
330 eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER);
332 /* the unknown map */
333 generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER);
337 /*-----------------------------------------------------------------*/
338 /* allocIntoSeg - puts a symbol into a memory segment */
339 /*-----------------------------------------------------------------*/
341 allocIntoSeg (symbol * sym)
343 memmap *segment = SPEC_OCLS (sym->etype);
344 addSet (&segment->syms, sym);
345 if (segment == pdata)
349 /*-----------------------------------------------------------------*/
350 /* deleteFromSeg - deletes a symbol from segment used when a var */
351 /* first declared as "extern" then no extern */
352 /*-----------------------------------------------------------------*/
353 void deleteFromSeg(symbol *sym)
355 if (SPEC_OCLS(sym->etype)) {
356 memmap *segment = SPEC_OCLS (sym->etype);
357 deleteSetItem(&segment->syms,sym);
361 /*-----------------------------------------------------------------*/
362 /* allocDefault - assigns the output segment based on SCLASS */
363 /*-----------------------------------------------------------------*/
365 allocDefault (symbol * sym)
367 switch (SPEC_SCLS (sym->etype))
370 SPEC_OCLS (sym->etype) = sfr;
373 SPEC_OCLS (sym->etype) = sfrbit;
378 /* if code change to constant */
379 if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
380 SPEC_OCLS(sym->etype) = c_abs;
382 SPEC_OCLS (sym->etype) = statsg;
386 // should we move this to the initialized data segment?
387 if (port->genXINIT &&
388 sym->ival && (sym->level==0) && !SPEC_ABSA (sym->etype)) {
389 SPEC_OCLS(sym->etype) = xidata;
391 SPEC_OCLS (sym->etype) = xdata;
395 /* absolute initialized global */
396 if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
397 SPEC_OCLS(sym->etype) = d_abs;
399 SPEC_OCLS (sym->etype) = data;
403 /* absolute initialized global */
404 if (sym->ival && (sym->level==0) && SPEC_ABSA (sym->etype)) {
405 SPEC_OCLS(sym->etype) = i_abs;
407 SPEC_OCLS (sym->etype) = idata;
412 SPEC_OCLS (sym->etype) = pdata;
416 SPEC_OCLS (sym->etype) = bit;
419 SPEC_OCLS (sym->etype) = eeprom;
428 /*-----------------------------------------------------------------*/
429 /* allocGlobal - assigns the output segment to a global var */
430 /*-----------------------------------------------------------------*/
432 allocGlobal (symbol * sym)
435 /* symbol name is internal name */
436 if (!sym->level) /* local statics can come here */
437 SNPRINTF (sym->rname, sizeof(sym->rname),
438 "%s%s", port->fun_prefix, sym->name);
440 /* add it to the operandKey reset */
441 if (!isinSet (operKeyReset, sym)) {
442 addSet(&operKeyReset, sym);
445 /* if this is a literal e.g. enumerated type */
446 /* put it in the data segment & do nothing */
447 if (IS_LITERAL (sym->etype))
449 SPEC_OCLS (sym->etype) = data;
453 /* if this is a function then assign code space */
454 if (IS_FUNC (sym->type))
456 SPEC_OCLS (sym->etype) = code;
457 /* if this is an interrupt service routine
458 then put it in the interrupt service array */
459 if (FUNC_ISISR (sym->type) && !options.noiv
460 && (FUNC_INTNO (sym->type) != INTNO_UNSPEC))
462 if (interrupts[FUNC_INTNO (sym->type)])
463 werror (E_INT_DEFINED,
464 FUNC_INTNO (sym->type),
465 interrupts[FUNC_INTNO (sym->type)]->name);
467 interrupts[FUNC_INTNO (sym->type)] = sym;
469 /* automagically extend the maximum interrupts */
470 if (FUNC_INTNO (sym->type) >= maxInterrupts)
471 maxInterrupts = FUNC_INTNO (sym->type) + 1;
473 /* if it is not compiler defined */
480 /* if this is a bit variable and no storage class */
481 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
482 /*&& SPEC_SCLS (sym->etype) == S_BIT*/
484 SPEC_OCLS (sym->type) = bit;
489 if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level))
490 /* register storage class ignored changed to FIXED */
491 if (SPEC_SCLS (sym->etype) == S_REGISTER)
492 SPEC_SCLS (sym->etype) = S_FIXED;
494 /* if it is fixed, then allocate depending on the */
495 /* current memory model, same for automatics */
496 if (SPEC_SCLS (sym->etype) == S_FIXED ||
497 (TARGET_IS_PIC16 && (SPEC_SCLS (sym->etype) == S_REGISTER) && (sym->level==0)) ||
498 SPEC_SCLS (sym->etype) == S_AUTO) {
499 if (port->mem.default_globl_map != xdata) {
500 /* set the output class */
501 SPEC_OCLS (sym->etype) = port->mem.default_globl_map;
502 /* generate the symbol */
506 SPEC_SCLS (sym->etype) = S_XDATA;
514 /*-----------------------------------------------------------------*/
515 /* allocParms - parameters are always passed on stack */
516 /*-----------------------------------------------------------------*/
518 allocParms (value * val)
523 for (lval = val; lval; lval = lval->next, pNum++)
525 /* check the declaration */
526 checkDecl (lval->sym, 0);
528 /* if this a register parm then allocate
529 it as a local variable by adding it
530 to the first block we see in the body */
531 if (IS_REGPARM (lval->etype))
534 /* mark it as my parameter */
535 lval->sym->ismyparm = 1;
536 lval->sym->localof = currFunc;
538 /* if automatic variables r 2b stacked */
539 if (options.stackAuto || IFFUNC_ISREENT (currFunc->type))
542 lval->sym->onStack = 1;
544 /* choose which stack 2 use */
545 /* use xternal stack */
546 if (options.useXstack)
548 /* PENDING: stack direction support */
549 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack;
550 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
551 xstackPtr - getSize (lval->type);
552 xstackPtr -= getSize (lval->type);
555 { /* use internal stack */
556 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack;
557 if (port->stack.direction > 0)
559 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
560 stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) -
561 getSize (lval->type) -
562 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0);
563 stackPtr -= getSize (lval->type);
567 /* This looks like the wrong order but it turns out OK... */
568 /* PENDING: isr, bank overhead, ... */
569 SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack =
571 ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) +
572 (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) +
574 stackPtr += getSize (lval->type);
577 allocIntoSeg (lval->sym);
580 { /* allocate them in the automatic space */
581 /* generate a unique name */
582 SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname),
583 "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
584 strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
586 /* if declared in specific storage */
587 if (allocDefault (lval->sym))
589 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype);
593 /* otherwise depending on the memory model */
594 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
595 port->mem.default_local_map;
596 if (options.model == MODEL_SMALL)
598 /* note here that we put it into the overlay segment
599 first, we will remove it from the overlay segment
600 after the overlay determination has been done */
601 if (!options.noOverlay)
603 SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) =
607 else if (options.model == MODEL_MEDIUM)
609 SPEC_SCLS (lval->etype) = S_PDATA;
613 SPEC_SCLS (lval->etype) = S_XDATA;
615 allocIntoSeg (lval->sym);
621 /*-----------------------------------------------------------------*/
622 /* deallocParms - parameters are always passed on stack */
623 /*-----------------------------------------------------------------*/
625 deallocParms (value * val)
629 for (lval = val; lval; lval = lval->next)
631 /* unmark is myparm */
632 lval->sym->ismyparm = 0;
634 /* delete it from the symbol table */
635 deleteSym (SymbolTab, lval->sym, lval->sym->name);
637 if (!lval->sym->isref)
639 lval->sym->allocreq = 0;
640 werror (W_NO_REFERENCE,
641 currFunc ? currFunc->name : "(unknown)",
642 "function argument", lval->sym->name);
645 /* move the rname if any to the name for both val & sym */
646 /* and leave a copy of it in the symbol table */
647 if (lval->sym->rname[0])
649 char buffer[SDCC_NAME_MAX];
650 strncpyz (buffer, lval->sym->rname, sizeof(buffer));
651 lval->sym = copySymbol (lval->sym);
652 strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname));
653 strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name));
654 strncpyz (lval->name, buffer, sizeof(lval->name));
655 addSym (SymbolTab, lval->sym, lval->sym->name,
656 lval->sym->level, lval->sym->block, 1);
657 lval->sym->_isparm = 1;
658 if (!isinSet (operKeyReset, lval->sym))
660 addSet(&operKeyReset, lval->sym);
667 /*-----------------------------------------------------------------*/
668 /* allocLocal - allocate local variables */
669 /*-----------------------------------------------------------------*/
671 allocLocal (symbol * sym)
673 /* generate an unique name */
674 SNPRINTF (sym->rname, sizeof(sym->rname),
677 currFunc->name, sym->name, sym->level, sym->block);
680 sym->localof = currFunc;
682 /* if this is a static variable */
683 if (IS_STATIC (sym->etype))
690 /* if volatile then */
691 if (IS_VOLATILE (sym->etype))
694 /* this is automatic */
696 /* if it's to be placed on the stack */
697 if (options.stackAuto || reentrant) {
699 if (options.useXstack) {
700 /* PENDING: stack direction for xstack */
701 SPEC_OCLS (sym->etype) = xstack;
702 SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1);
703 xstackPtr += getSize (sym->type);
705 SPEC_OCLS (sym->etype) = istack;
706 if (port->stack.direction > 0) {
707 SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1);
708 stackPtr += getSize (sym->type);
710 stackPtr -= getSize (sym->type);
711 SPEC_STAK (sym->etype) = sym->stack = stackPtr;
718 /* else depending on the storage class specified */
720 /* if this is a function then assign code space */
721 if (IS_FUNC (sym->type))
723 SPEC_OCLS (sym->etype) = code;
727 /* if this is a bit variable and no storage class */
728 if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT)
730 SPEC_SCLS (sym->type) = S_BIT;
731 SPEC_OCLS (sym->type) = bit;
736 if ((SPEC_SCLS (sym->etype) == S_DATA) || (SPEC_SCLS (sym->etype) == S_REGISTER))
738 SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay);
743 if (allocDefault (sym))
748 /* again note that we have put it into the overlay segment
749 will remove and put into the 'data' segment if required after
750 overlay analysis has been done */
751 if (options.model == MODEL_SMALL) {
752 SPEC_OCLS (sym->etype) =
753 (options.noOverlay ? port->mem.default_local_map : overlay);
755 SPEC_OCLS (sym->etype) = port->mem.default_local_map;
760 /*-----------------------------------------------------------------*/
761 /* deallocLocal - deallocates the local variables */
762 /*-----------------------------------------------------------------*/
764 deallocLocal (symbol * csym)
768 for (sym = csym; sym; sym = sym->next)
773 /* if it is on the stack */
776 if (options.useXstack)
777 xstackPtr -= getSize (sym->type);
779 stackPtr -= getSize (sym->type);
781 /* if not used give a warning */
782 if (!sym->isref && !IS_STATIC (sym->etype))
783 werror (W_NO_REFERENCE,
784 currFunc ? currFunc->name : "(unknown)",
785 "local variable", sym->name);
786 /* now delete it from the symbol table */
787 deleteSym (SymbolTab, sym, sym->name);
791 /*-----------------------------------------------------------------*/
792 /* overlay2data - moves declarations from the overlay seg to data */
793 /*-----------------------------------------------------------------*/
799 for (sym = setFirstItem (overlay->syms); sym;
800 sym = setNextItem (overlay->syms))
803 SPEC_OCLS (sym->etype) = data;
807 setToNull ((void *) &overlay->syms);
811 /*-----------------------------------------------------------------*/
812 /* overlay2Set - will add all symbols from the overlay segment to */
813 /* the set of sets containing the overlable symbols */
814 /*-----------------------------------------------------------------*/
821 for (sym = setFirstItem (overlay->syms); sym;
822 sym = setNextItem (overlay->syms))
828 setToNull ((void *) &overlay->syms);
829 addSet (&ovrSetSets, oset);
833 /*-----------------------------------------------------------------*/
834 /* allocVariables - creates decl & assign storage class for a v */
835 /*-----------------------------------------------------------------*/
837 allocVariables (symbol * symChain)
844 /* go thru the symbol chain */
845 for (sym = symChain; sym; sym = sym->next)
848 /* if this is a typedef then add it */
849 /* to the typedef table */
850 if (IS_TYPEDEF (sym->etype))
852 /* check if the typedef already exists */
853 csym = findSym (TypedefTab, NULL, sym->name);
854 if (csym && csym->level == sym->level)
855 werror (E_DUPLICATE_TYPEDEF, sym->name);
857 SPEC_EXTR (sym->etype) = 0;
858 addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0);
859 continue; /* go to the next one */
861 /* make sure it already exist */
862 csym = findSymWithLevel (SymbolTab, sym);
863 if (!csym || (csym && csym->level != sym->level))
866 /* check the declaration */
869 /* if this is a function or a pointer to function */
870 /* then args processing */
871 if (funcInChain (csym->type))
873 processFuncArgs (csym);
875 /* if register bank specified then update maxRegBank */
876 if (maxRegBank < FUNC_REGBANK (csym->type))
877 maxRegBank = FUNC_REGBANK (csym->type);
878 /*JCF: Mark the register bank as used*/
879 RegBankUsed[FUNC_REGBANK(csym->type)]=1;
882 /* if this is a extern variable then change the */
883 /* level to zero temporarily */
884 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
886 saveLevel = csym->level;
890 /* if this is a literal then it is an enumerated */
891 /* type so need not allocate it space for it */
892 if (IS_LITERAL (sym->etype))
895 /* generate the actual declaration */
900 stack += getSize (csym->type);
905 /* restore the level */
906 if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type))
907 csym->level = saveLevel;
913 /*-----------------------------------------------------------------*/
914 /* redoStackOffsets :- will reassign the values for stack offsets */
915 /*-----------------------------------------------------------------*/
917 redoStackOffsets (void)
923 /* after register allocation is complete we know
924 which variables will need to be assigned space
925 on the stack. We will eliminate those variables
926 which do not have the allocReq flag thus reducing
928 for (sym = setFirstItem (istack->syms); sym;
929 sym = setNextItem (istack->syms))
932 int size = getSize (sym->type);
933 /* nothing to do with parameters so continue */
934 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
937 if (IS_AGGREGATE (sym->type))
939 if (port->stack.direction > 0)
941 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
947 SPEC_STAK (sym->etype) = sym->stack = sPtr;
952 /* if allocation not required then subtract
953 size from overall stack size & continue */
956 currFunc->stack -= size;
957 SPEC_STAK (currFunc->etype) -= size;
961 if (port->stack.direction > 0)
963 SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1);
969 SPEC_STAK (sym->etype) = sym->stack = sPtr;
973 /* do the same for the external stack */
975 for (sym = setFirstItem (xstack->syms); sym;
976 sym = setNextItem (xstack->syms))
979 int size = getSize (sym->type);
980 /* nothing to do with parameters so continue */
981 if ((sym->_isparm && !IS_REGPARM (sym->etype)))
984 if (IS_AGGREGATE (sym->type))
986 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
991 /* if allocation not required then subtract
992 size from overall stack size & continue */
995 currFunc->xstack -= size;
996 SPEC_STAK (currFunc->etype) -= size;
1000 SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1);
1006 /*-----------------------------------------------------------------*/
1007 /* printAllocInfoSeg- print the allocation for a given section */
1008 /*-----------------------------------------------------------------*/
1010 printAllocInfoSeg (memmap * map, symbol * func, struct dbuf_s *oBuf)
1019 for (sym = setFirstItem (map->syms); sym;
1020 sym = setNextItem (map->syms))
1023 if (sym->level == 0)
1025 if (sym->localof != func)
1028 dbuf_printf (oBuf, ";%-25s Allocated ", sym->name);
1030 /* if assigned to registers */
1031 if (!sym->allocreq && sym->reqv)
1035 sym = OP_SYMBOL (sym->reqv);
1036 if (!sym->isspilt || sym->remat)
1038 dbuf_append_str (oBuf, "to registers ");
1039 for (i = 0; i < 4 && sym->regs[i]; i++)
1040 dbuf_printf (oBuf, "%s ", port->getRegName (sym->regs[i]));
1041 dbuf_append_char (oBuf, '\n');
1046 sym = sym->usl.spillLoc;
1053 dbuf_printf (oBuf, "to stack - offset %d\n", sym->stack);
1057 /* otherwise give rname */
1058 dbuf_printf (oBuf, "with name '%s'\n", sym->rname);
1062 /*-----------------------------------------------------------------*/
1063 /* canOverlayLocals - returns true if the local variables can overlayed */
1064 /*-----------------------------------------------------------------*/
1066 canOverlayLocals (eBBlock ** ebbs, int count)
1069 /* if staticAuto is in effect or the current function
1070 being compiled is reentrant or the overlay segment
1071 is empty or no overlay option is in effect then */
1072 if (options.noOverlay ||
1073 options.stackAuto ||
1075 (IFFUNC_ISREENT (currFunc->type) ||
1076 FUNC_ISISR (currFunc->type))) ||
1077 elementsInSet (overlay->syms) == 0)
1081 /* if this is a forces overlay */
1082 if (IFFUNC_ISOVERLAY(currFunc->type)) return TRUE;
1084 /* otherwise do thru the blocks and see if there
1085 any function calls if found then return false */
1086 for (i = 0; i < count; i++)
1090 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1092 if (ic->op == CALL) {
1093 sym_link *ftype = operandType(IC_LEFT(ic));
1094 /* builtins only can use overlays */
1095 if (!IFFUNC_ISBUILTIN(ftype)) return FALSE;
1096 } else if (ic->op == PCALL) return FALSE;
1100 /* no function calls found return TRUE */
1104 /*-----------------------------------------------------------------*/
1105 /* doOverlays - move the overlay segment to appropriate location */
1106 /*-----------------------------------------------------------------*/
1108 doOverlays (eBBlock ** ebbs, int count)
1114 /* check if the parameters and local variables
1115 of this function can be put in the overlay segment
1116 This check is essentially to see if the function
1117 calls any other functions if yes then we cannot
1119 if (canOverlayLocals (ebbs, count))
1120 /* if we can then put the parameters &
1121 local variables in the overlay set */
1124 /* otherwise put them into data where
1129 /*-----------------------------------------------------------------*/
1130 /* printAllocInfo - prints allocation information for a function */
1131 /*-----------------------------------------------------------------*/
1133 printAllocInfo (symbol * func, struct dbuf_s * oBuf)
1138 /* must be called after register allocation is complete */
1139 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
1140 dbuf_printf (oBuf, ";Allocation info for local variables in function '%s'\n", func->name);
1141 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");
1143 printAllocInfoSeg (xstack, func, oBuf);
1144 printAllocInfoSeg (istack, func, oBuf);
1145 printAllocInfoSeg (code, func, oBuf);
1146 printAllocInfoSeg (data, func, oBuf);
1147 printAllocInfoSeg (xdata, func, oBuf);
1148 printAllocInfoSeg (idata, func, oBuf);
1149 printAllocInfoSeg (sfr, func, oBuf);
1150 printAllocInfoSeg (sfrbit, func, oBuf);
1154 set *tempOverlaySyms = overlay->syms;
1156 /* search the set of overlay sets for local variables/parameters */
1157 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1158 ovrset = setNextItem (ovrSetSets))
1160 overlay->syms = ovrset;
1161 printAllocInfoSeg (overlay, func, oBuf);
1163 overlay->syms = tempOverlaySyms;
1166 dbuf_append_str (oBuf, ";------------------------------------------------------------\n");